skip to Main Content

I have different projects, in some of them it is fairly simple to access configuration items, in others it’s not – and I have difficulties finding out why. All are .NET 6 projects.

Note I have checked out some questions that looked similar as well as MS documentation but neither seems to work. Kindly read through my question before flagging it as duplicate.

How it works in a Function App:

In my Startup.cs file I have this:

    public override void Configure(IFunctionsHostBuilder builder)
    {
        [...]
        // This is not really relevant but you see how I access configuration settings
        builder.Services.AddHttpClient("MyClient", client =>
        {
            client.BaseAddress = new Uri(C.Configuration.GetValue<string>("BaseAddress"));
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("Authorization",  $"Bearer {C.Configuration.GetValue<string>("ApiToken")}");  
        });
        [...]
    }

    public override void ConfigureAppConfiguration(IFunctionsConfigurationBuilder builder)
    {
        builder.ConfigurationBuilder
            .SetBasePath(Environment.CurrentDirectory)
            .AddJsonFile("local.settings.json", true)
            .AddUserSecrets(Assembly.GetExecutingAssembly(), true)
            .AddEnvironmentVariables()
            .Build();
    }

Also, I have a static class C that holds all kinds of constants – as well as the configuration. I post the relevant part as a screenshot on purpose, you’ll understand why.
Function app C.cs

So far, so good – in any place of the whole Function App project I can access any configuration setting by using C.Configuration.GetValue<Type>("setting").

How it does not work in an App Service

Now I have an App Service – and all I want is the exactly same functionality. However, it does not work, Configuration is null. The relevant part of C.cs looks exactly the same:
App service C.cs
You’ll notice, however, that in one case the line using Microsoft.Extensions.Configuration; is greyed out by VS which means it is considered obsolete, while this is not the case in the Function App C.cs.

I assumed this must have something to do with the startup configuration or dependency injection, so I tried to configure it the same way as in the Function App. This is what I added to my Program.cs which obviously is the equivalent to Startup.cs in a Function App:

builder.Configuration
    .SetBasePath(Environment.CurrentDirectory)
    .AddJsonFile("appsettings.json", true)
    .AddUserSecrets(Assembly.GetExecutingAssembly(), true)
    .AddEnvironmentVariables()
    .Build();
    
    ConfigurationManager configuration = builder.Configuration; 

The configuration is even added as a DI Singleton:

builder.Services.AddSingleton<IConfiguration>(configuration);

Now you probably ask why I want to have the configuration in that C class when it’s there as an injectable singleton. From what I understand the singleton is injected in my Controller classes – but I have lots of other classes that need to get values from the configuration. I am perfectly aware that I could pass down the configuration object to all dependent classes as a parameter in the constructor. This concept of DI is absolutely legit, but I consider it a bit over the top when it comes to configuration items. Just calling

`C.Configuration.GetValue<Type>("setting")`

anywhere in the code seems more convenient and logical to me. Note that C is not a singleton class but rather a static class – and since this works in the Function App, I had hoped it would work in the App service project as well.

Anyone can point me in the right direction? Happy to share more code snippets if required.

2

Answers


  1. These are some OAuth request samples. I think this will help you to get some idea about the OAuth request.

     public async Task<string> SynchEntitiesOAuthGET(SynchParameterModel model)
            {
                string response = string.Empty;
                try
                {
                    var access_token = ÒAuthConnector.GetOAuthToken(_eagleSettings.OAuthTokenIssuerURL, _eagleSettings.OAuthClientId, _eagleSettings.OAuthClientSecret, _eagleSettings.OAuthScope);
    
                    HttpResponseMessage responseMessage;
                    using (HttpClient httpClient = new HttpClient())
                    {
                        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
                        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, model.APIEndPoint);
                        responseMessage =await httpClient.SendAsync(request);
                    }
    
                    response =await responseMessage.Content.ReadAsStringAsync();
                }
                catch (WebException ex)
                {
                    ExceptionWeb(ex, model.RecordType);
                }
                catch (Exception ex)
                {
                    ExceptionSystem(ex, model.RecordType);
                }
    
                return response;
            }
            public async Task<string> SynchEntitiesOAuthPOST(SynchParameterModel model)
            {
                string response = string.Empty;
                try
                {
                    var access_token = ÒAuthConnector.GetOAuthToken(_eagleSettings.OAuthTokenIssuerURL, _eagleSettings.OAuthClientId, _eagleSettings.OAuthClientSecret, _eagleSettings.OAuthScope);
    
                    var bodyJson = model.RequestBody;// JsonSerializer.Serialize(model.RequestBody);
                    var stringContent = new StringContent(bodyJson, Encoding.UTF8, "application/json");
    
    
                    HttpResponseMessage responseMessage;
                    using (HttpClient httpClient = new HttpClient())
                    {
                        httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
                        responseMessage =await httpClient.PostAsync(model.APIEndPoint, stringContent);
                    }
    
                    response = await responseMessage.Content.ReadAsStringAsync();
                }
                catch (WebException ex)
                {
                    ExceptionWeb(ex, model.RecordType);
                }
                catch (Exception ex)
                {
                    ExceptionSystem(ex, model.RecordType);
                }
    
                return response;
            }
    
            public string SynchEntitiesBasicAuthenticationPOST(SynchParameterModel model)
            {
                var response = string.Empty;
                try
                {
                    string username = _eagleSettings.WebServiceUser;
                    string password = _eagleSettings.WebServicePassword;
    
                    WebRequest req = WebRequest.Create(model.APIEndPoint);
                    req.Method = "POST";
                    req.ContentType = "application/json";
                    req.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
                    req.Timeout = int.MaxValue;
    
                    using (var streamWriter = new StreamWriter(req.GetRequestStream()))
                    {
                        string json = model.RequestBody;
                        streamWriter.Write(json);
                    }
    
                    HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
    
                    var encoding = ASCIIEncoding.ASCII;
                    using (var reader = new System.IO.StreamReader(resp.GetResponseStream(), encoding))
                    {
                        response = reader.ReadToEnd();
                    }
                }
                catch (WebException ex)
                {
                    ExceptionWeb(ex, model.RecordType);
                }
                catch (Exception ex)
                {
                    ExceptionSystem(ex, model.RecordType);
                }
    
                return response;
            }
    
            public string SynchEntitiesBasicAuthenticationGET(SynchParameterModel model)
            {
                string response = string.Empty;
                try
                {
                    string username = _eagleSettings.WebServiceUser;
                    string password = _eagleSettings.WebServicePassword;
    
                    WebRequest req = WebRequest.Create(model.APIEndPoint);
                    req.Method = "GET";
                    req.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.Default.GetBytes(username + ":" + password));
                    req.Timeout = int.MaxValue;
    
                    HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
    
                    var encoding = ASCIIEncoding.ASCII;
                    using (var reader = new System.IO.StreamReader(resp.GetResponseStream(), encoding))
                    {
                        response = reader.ReadToEnd();
                    }
                }
                catch (WebException ex)
                {
                    ExceptionWeb(ex, model.RecordType);
                }
                catch (Exception ex)
                {
                    ExceptionSystem(ex, model.RecordType);
                }
    
                return response;
            }
    

    SynchParameterModel class

     public partial class SynchParameterModel
        {
            /// <summary>
            /// Get or set Record type for sync entity
            /// </summary>
            public string RecordType { get; set; }
    
            /// <summary>
            /// Get or set API end point for get record
            /// </summary>
            public string APIEndPoint { get; set; }
    
            /// <summary>
            /// Get or set from sync date time
            /// </summary>
            public DateTime FromDateTime { get; set; }
    
            /// <summary>
            /// Get or set to sync date time
            /// </summary>
            public DateTime ToDateTime { get; set; }
    
            /// <summary>
            /// Get or set to request type. this should be GET or POST
            /// </summary>
            public string RequestType { get; set; }
    
            /// <summary>
            /// Get or set to request body. this should POST request
            /// </summary>
            public string RequestBody { get; set; }
        }
    
    Login or Signup to reply.
  2. Are you ever actually calling C.Configuration = XXX anywhere? I see in your code screenshots that you’re using the configuration builder to setup IConfiguration for dependency injection, but nowhere are you assigning it to your static C.Configuration property.

    Maybe it’s something as simple as

    C.Configuration = builder.Configuration
        .SetBasePath(Environment.CurrentDirectory)
        .AddJsonFile("appsettings.json", true)
        .AddUserSecrets(Assembly.GetExecutingAssembly(), true)
        .AddEnvironmentVariables()
        .Build();
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search