0

I am not able to get value of PContextFactory through dependency injection.

below are the code.

  • Startup.cs
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using EZTrackCaseWare.FunctionApp.Helpers;
using EZTrackCaseWare.FunctionApp.Options;
using EZTrackCaseWare.FunctionApp.Validation;
using FluentValidation;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using PnP.Core.Auth.Services.Builder.Configuration;
using PnP.Core.Services;

[assembly: InternalsVisibleTo("EZTrackCaseWare.FunctionApp.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: FunctionsStartup(typeof(EZTrackCaseWare.FunctionApp.Startup))]

namespace EZTrackCaseWare.FunctionApp
{
    [ExcludeFromCodeCoverage] // Justification = "This class cannot be tested."
    public class Startup : FunctionsStartup
    {
        private readonly ConfigurationOptions configOptions;

        public Startup()
        {
            this.configOptions = new ConfigurationOptions();

            ValidatorOptions.Global.DisplayNameResolver = (type, memberInfo, lambdaExpression) => memberInfo.Name;
            ValidatorOptions.Global.LanguageManager = new CustomLanguageManager();
        }

        public override void Configure(IFunctionsHostBuilder builder)
        {
            // options
            builder.Services.AddOptions<ConfigurationOptions>()
                   .Configure<IConfiguration>(
                        (settings, configuration) =>
                        {
                            configuration.GetSection(nameof(ConfigurationOptions)).Bind(settings);
                        });

            // helpers
            builder.Services.AddSingleton<IAzureStorageHelper, AzureStorageHelper>()
                   .AddSingleton<IEnvironmentHelper, EnvironmentHelper>()
                   .AddSingleton<IJsonHelper, JsonHelper>()
                   .AddSingleton<ISpoHelper, SpoHelper>()
                   .AddSingleton<IAzureStorageHelper, AzureStorageHelper>();

            // Add and configure PnP Core SDK
            builder.Services.AddPnPCoreAuthentication(
                options =>
                {
                    // Load the certificate to use
                    var cert = this.LoadCertificate();

                    // Configure certificate based auth
                    options.Credentials.Configurations.Add(
                        "CertAuth",
                        new PnPCoreAuthenticationCredentialConfigurationOptions
                        {
                            ClientId = this.configOptions.AzureAppRegistration.ClientId,
                            TenantId = this.configOptions.AzureAppRegistration.TenantId,
                            X509Certificate = new PnPCoreAuthenticationX509CertificateOptions { Certificate = this.LoadCertificate(), }
                        });

                    // Connect this auth method to the configured site
                    options.Sites.Add("Default", new PnPCoreAuthenticationSiteOptions { AuthenticationProviderName = "CertAuth", });
                });
        }

        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
        {
            var context = builder.GetContext();

            builder.ConfigurationBuilder.SetBasePath(context.ApplicationRootPath)
                   .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
                   .AddJsonFile("appsettings.local.json", optional: true, reloadOnChange: false)
                   .AddJsonFile("local.settings.json", true, false)
                   .AddEnvironmentVariables();
        }

        public X509Certificate2 LoadCertificate()
        {
            // Will only be populated correctly when running in the Azure Function host
            var certBase64Encoded = Environment.GetEnvironmentVariable(Constants.KeyVault.EzTrackCertificate);

            if (!string.IsNullOrEmpty(certBase64Encoded))
            {
                // Azure Function flow
                return new X509Certificate2(
                    Convert.FromBase64String(certBase64Encoded),
                    string.Empty,
                    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.EphemeralKeySet);
            }
            else
            {
                // Local flow
                var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, this.configOptions.AzureAppRegistration.CertificateThumbprint, false);
                store.Close();

                return certificateCollection.First();
            }
        }
    }
}

  • SPOHelper.cs class
using System;
using System.IO;
using System.Threading.Tasks;
using PnP.Core.Services;

namespace EZTrackCaseWare.FunctionApp.Helpers
{
    public class SpoHelper : ISpoHelper
    {
        private readonly IPnPContextFactory contextFactory;

        public SpoHelper(IPnPContextFactory contextFactory)
        {
            this.contextFactory = contextFactory;
        }

        public async Task<Stream> DownLoadFileAsync(int siteId, string documentName)
        {
            Stream fileStream = null!;
            using var context = await this.contextFactory.CreateAsync(new Uri($"{Constants.SPO.Uri}/{siteId}"));

            var documentUrl = $"{context.Uri.PathAndQuery}/{Constants.SPO.EZTDocuments}/{documentName}";

            // Get a reference to the file
            var document = await context.Web.GetFileByServerRelativeUrlAsync(documentUrl);

            // Download the file as stream
            fileStream = await document.GetContentAsync();

            return fileStream;
        }
    }
}

- Screen Shot
[![Null Reference error][1]][1]


  [1]: https://i.sstatic.net/lsuIR.jpg

1 Answer 1

0

I was able to solve it by changing the startup.cs code.

below are the startup.cs code.

using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using EZTrackCaseWare.FunctionApp.Helpers;
using EZTrackCaseWare.FunctionApp.Options;
using EZTrackCaseWare.FunctionApp.Validation;
using FluentValidation;
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using PnP.Core.Auth;
using PnP.Core.Services.Builder.Configuration;

[assembly: InternalsVisibleTo("EZTrackCaseWare.FunctionApp.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: FunctionsStartup(typeof(EZTrackCaseWare.FunctionApp.Startup))]

namespace EZTrackCaseWare.FunctionApp
{
    [ExcludeFromCodeCoverage] // Justification = "This class cannot be tested."
    public class Startup : FunctionsStartup
    {
        private readonly ConfigurationOptions configOptions;

        public Startup()
        {
            this.configOptions = new ConfigurationOptions();

            ValidatorOptions.Global.DisplayNameResolver = (type, memberInfo, lambdaExpression) => memberInfo.Name;
            ValidatorOptions.Global.LanguageManager = new CustomLanguageManager();
        }

        public override void Configure(IFunctionsHostBuilder builder)
        {
            // options
            builder.Services.AddOptions<ConfigurationOptions>()
                   .Configure<IConfiguration>(
                        (settings, configuration) =>
                        {
                            configuration.GetSection(nameof(ConfigurationOptions)).Bind(settings);
                        });

            builder.GetContext().Configuration.GetSection(nameof(ConfigurationOptions)).Bind(this.configOptions);

            // helpers
            builder.Services.AddSingleton<IAzureStorageHelper, AzureStorageHelper>()
                   .AddSingleton<IEnvironmentHelper, EnvironmentHelper>()
                   .AddSingleton<IJsonHelper, JsonHelper>()
                   .AddSingleton<ISpoHelper, SpoHelper>()
                   .AddSingleton<IAzureStorageHelper, AzureStorageHelper>();

            builder.Services.AddPnPCore(
                options =>
                {
                    options.PnPContext.GraphFirst = true;
                    options.PnPContext.GraphCanUseBeta = true;

                    options.PnPContext.GraphAlwaysUseBeta = true;
                    options.HttpRequests.UserAgent = "NONISV|SharePointPnP|PnPCoreSDK";

                    options.HttpRequests.MicrosoftGraph = new PnPCoreHttpRequestsGraphOptions
                    {
                        UseRetryAfterHeader = true,
                        MaxRetries = 10,
                        DelayInSeconds = 3,
                        UseIncrementalDelay = true,
                    };

                    options.HttpRequests.SharePointRest = new PnPCoreHttpRequestsSharePointRestOptions
                    {
                        UseRetryAfterHeader = true,
                        MaxRetries = 10,
                        DelayInSeconds = 3,
                        UseIncrementalDelay = true,
                    };

                    options.DefaultAuthenticationProvider = new X509CertificateAuthenticationProvider(this.configOptions.AzureAppRegistration.ClientId, this.configOptions.AzureAppRegistration.TenantId, this.LoadCertificate());
                });
        }

        public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
        {
            var context = builder.GetContext();

            builder.ConfigurationBuilder.SetBasePath(context.ApplicationRootPath)
                   .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
                   .AddJsonFile("appsettings.local.json", optional: true, reloadOnChange: false)
                   .AddJsonFile("local.settings.json", true, false)
                   .AddEnvironmentVariables();
        }

        public X509Certificate2 LoadCertificate()
        {
            // Will only be populated correctly when running in the Azure Function host
            var certBase64Encoded = Environment.GetEnvironmentVariable(Constants.KeyVault.EzTrackCertificate);

            if (!string.IsNullOrEmpty(certBase64Encoded))
            {
                // Azure Function flow
                return new X509Certificate2(
                    Convert.FromBase64String(certBase64Encoded),
                    string.Empty,
                    X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.EphemeralKeySet);
            }
            else
            {
                // Local flow
                var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
                var certificateCollection = store.Certificates.Find(X509FindType.FindByThumbprint, this.configOptions.AzureAppRegistration.CertificateThumbprint, false);
                store.Close();

                return certificateCollection.First();
            }
        }
    }
}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.