1

I am trying to access AppSettings as service in my ASP.NET core WebAPI. When I do Configuration.GetSection("AppSettings") I get null but I could access the configuration values as Configuration["AppSettings:StorageConnectionKey:AccountName"]. I am not sure what I am doing wrong.

My Startup.cs is shown below

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Library;

namespace Athraya
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json")
               // .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();
            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; set; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();

            services.AddOptions();


            services.Configure<AppSettings>(options => Configuration.GetSection("AppSettings"));

            // *If* you need access to generic IConfiguration this is **required**
            services.AddSingleton<IConfiguration>(Configuration);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();

            app.UseMvc();
        }
    }
}

and my appsetting is

    {
  "AppSettings": {
    "StorageConnectionKey": {
      "AccountName": "myaccountName",
      "AccountKey": "abc"

    },
    "CloudContainerkey": {
      "ContainerName": "mycontainername",
      "FileName": "db.dat"
    }
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}

I have a Library Project where I have the classes needed

    using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Library
{
    public class AppSettings
    {
        public StorageConnectionKey storageKey {get; set; }
        public CloudContainerKey containerKey { get; set; }
    }
}

    namespace Library
{
    public class CloudContainerKey
    {
        public string ContainerName { get; set; }
        public string FileName { get; set; }
    }
}

    namespace Library
{
    public class StorageConnectionKey
    {
        public string AccountName { get; set; }
        public string AccountKey { get; set; }
    }
}

I am trying to get it in controller as

public class ValuesController : Controller
    {
        private readonly AppSettings _appSettings;

        public ValuesController(IOptions<AppSettings> settings)
        {
            _appSettings = settings.Value;
        }
}

Any Help here is appreciated.

3 Answers 3

1

To setup AppSettings using IConfiguration instance use:

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

Also, you need to use the same property name, as your settings parameters. Modify your AppSettings to:

public class AppSettings
{
    public StorageConnectionKey StorageConnectionKey {get; set; }
    public CloudContainerKey CloudContainerKey { get; set; }
}

In your case, you have null, as you use the extension method, that allows registering an action used to configure option manually. If you look into method definition, you will see:

//
// Summary:
//     Registers an action used to configure a particular type of options. ///
//
// Parameters:
//   services:
//     The Microsoft.Extensions.DependencyInjection.IServiceCollection to add the services
//     to.
//
//   configureOptions:
//     The action used to configure the options.
//
// Type parameters:
//   TOptions:
//     The options type to be configured.
//
// Returns:
//     The Microsoft.Extensions.DependencyInjection.IServiceCollection so that additional
//     calls can be chained.
public static IServiceCollection Configure<TOptions>(this IServiceCollection services,
     Action<TOptions> configureOptions) where TOptions : class;

In other words, when you use follow code, you register the lambda function and already use the instance of AppSettings:

services.Configure<AppSettings>(option =>
{
    // option here is the AppSettings and so we can override value like:
    option.StorageConnectionKey = "some_new_value";
});
Sign up to request clarification or add additional context in comments.

4 Comments

I still get null when you have it that way services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
How do you think I should change my startup so i can access it in the controller as I have mentioned. I tried to follow this blog codefluff.com/getting-configuration-settings-asp-net-core-mvc. Please let me know what I am missing is something changed in ASP.NET Core again
@Vijayaravind have updated answer - you need to rename propertis in your option classes to be the same, as setting parameters names.
Thank you so much. that was it. I did not realize that at all.. Appreciate your help.
0

I think it should be like this:

services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));

1 Comment

This is how I originally had it and I still got Null so I changed it based on this blog weblog.west-wind.com/posts/2016/may/23/…
0

Let's say you have following settings

"MyApplication": {
    "Name": "Demo Configuration Application (Development)",
    "Version": "1.1",
    "DefaultUrl": "http://localhost:3030",
    "Support": {
      "Email": "[email protected]",
      "Phone": "123456789"
  }
}

First you need to create corresponding C# classes where property names should match with the above JSON settings.

public class ApplicationOptions
{
     public const string MyApplication = "MyApplication";
 
     public string Name { get; set; }
     public decimal Version { get; set; }
     public string DefaultUrl { get; set; }
 
     public SupportOptions Support { get; set; }
}
 
public class SupportOptions
{
     public const string Support = "Support";
 
     public string Email { get; set; }
     public string Phone { get; set; }
}

Next you need to bind your configuration settings in Startup.cs file as follows:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<ApplicationOptions>(Configuration.GetSection(ApplicationOptions.MyApplication));     
    ...
}

Next you can inject the configuration in Controllers or Services using Options pattern

private readonly ApplicationOptions _options;
 
public HomeController(IOptions<ApplicationOptions> options)
{
    _options = options.Value;
}

Finally you can read settings as follows:

public IActionResult Index()
{
    ViewBag.ApplicationName = _options.Name;
    ViewBag.ApplicationVersion = _options.Version;
    ViewBag.ApplicationUrl = _options.DefaultUrl;
 
    ViewBag.SupportEmail = _options.Support.Email;
    ViewBag.SupportPhone = _options.Support.Phone;
 
    return View();
}

You can read my full blog post A Step by Step Guide for ASP.NET Core Configuration explaining all of these steps in greater detail.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.