84
public class Bar
{
    public static readonly string Foo = ConfigurationManager.AppSettings["Foo"];
}

In the .NET Framework 4.x, I can use the ConfigurationManager.AppSettings ["Foo"] to get Foo in Webconfig,and then I can easily get the value of Foo through Bar.Foo

But in .Net core, I mustto inject options, And can not get the value of Foothrough Bar.Foo

Is there a method, which can be directly through the Bar.Foo to get the value of Foo?

DavidG
  • 24,279
  • 14
  • 89
  • 82
ChiakiYu
  • 905
  • 1
  • 8
  • 7
  • Please find the below link the author has explained it very well http://stackoverflow.com/questions/31453495/how-to-read-appsettings-values-from-config-json-in-asp-net-core – IamChandu May 03 '17 at 10:17
  • I answered in following link :) (.net core 2.x stack-overflow)[https://stackoverflow.com/questions/46940710/getting-value-from-appsettings-json-in-net-core/46940811#answer-51780754] – shajji Aug 13 '18 at 04:26

8 Answers8

119

So there are really two ways to go about this.

Option 1 : Options Class

You have an appsettings.json file :

{
  "myConfiguration": {
    "myProperty": true 
  }
}

You create a Configuration POCO like so :

public class MyConfiguration
{
    public bool MyProperty { get; set; }
}

In your startup.cs you have something in your ConfigureServices that registers the configuration :

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MyConfiguration>(Configuration.GetSection("myConfiguration"));
}

Then in your controller/service you inject in the IOptions and it's useable.

public class ValuesController : Controller
{
    private readonly MyConfiguration _myConfiguration;

    public ValuesController(IOptions<MyConfiguration> myConfiguration)
    {
        _myConfiguration = myConfiguration.Value;
    }
}

Personally I don't like using IOptions because I think it drags along some extra junk that I don't really want, but you can do cool things like hot swapping and stuff with it.

Option 2 : Configuration POCO

It's mostly the same but in your Configure Services method you instead bind to a singleton of your POCO.

public void ConfigureServices(IServiceCollection services)
{
    //services.Configure<MyConfiguration>(Configuration.GetSection("myConfiguration"));
    services.AddSingleton(Configuration.GetSection("myConfiguration").Get<MyConfiguration>());
}

And then you can just inject the POCO directly :

public class ValuesController : Controller
{
    private readonly MyConfiguration _myConfiguration;

    public ValuesController(MyConfiguration myConfiguration)
    {
        _myConfiguration = myConfiguration;
    }
}

A little simplistic because you should probably use an interface to make unit testing a bit easier but you get the idea.

Mostly taken from here : http://dotnetcoretutorials.com/2016/12/26/custom-configuration-sections-asp-net-core/

MindingData
  • 11,924
  • 6
  • 49
  • 68
  • 7
    Thank you for your answer. However, both methods require `IOptions `or `MyConfiguration`. What should I do if I use static class / static properties? – ChiakiYu May 04 '17 at 02:21
  • 4
    @ChiakiYu you shoud not use static classes or properties for configuration - it is considered a bad practice – a.szechlicki Jun 01 '17 at 23:11
  • a little off-topic, but I don't agree with the bit on unit testing, and maybe that is a little bit out of context anyway. `MyConfiguration` is just a POCO, and you can easily provide a pre-made test version with your mocking framework of choice. So I'm not sure you *really* need an interface there. All in all, it does not have an implementation that you want to hide behind an interface. – superjos Oct 22 '17 at 11:08
  • Nice answer - exactly what I was looking for. Thanks. – blueprintchris Oct 30 '17 at 13:51
  • @MindingData I do have one question though: in the controller, if I change the concrete class to an interface the values in my dependency become null - any suggestions? – blueprintchris Oct 31 '17 at 09:51
  • @blueprintChris can you try services.AddSingleton. It will then bind the concrete class to your interface. – MindingData Oct 31 '17 at 18:53
  • when you are in your controller, where is the parameter being passed from? (IOptions myConfiguration) – software is fun Feb 21 '20 at 15:22
  • I think these should be more like Options 2 and 3, while Option 1 is actually what the others have answered (IConfiguration directly). In any case, to summarize, I'd say, those 3 ways together are basically the sensible options at your disposal. (ofc one could ignore the framework and import with File and then de-serialize, but I wouldn't recommend that.) – somedotnetguy Jun 19 '23 at 12:12
54

The solutions on top are time consuming and not straightforward, this is the best effective way to do it, no setup needed on startup or anything. It's like using the good ol Configuration.Manager.AppSettings["setting"]

First create a class like "Credential":

public class Credential
  {
      public string Username {get;set}
      public string Password {get;set;}
  }

Now that's setup let put the IConfiguration on your constructor like so:

    private IConfiguration _configuration;
    public ValuesController(IConfiguration iconfig)
    {
        _configuration = iconfig;
    }

Then you're ready to call it!

    Credential c = new Credential();
    c.UserName = _configuration.GetValue<string>("Credential:username");
    c.Password = _configuration.GetValue<string>("Credential:password");

Assuming your appsettings.json looks like this:

"Credential": {
    "username": "myuser",
    "password": "mypassword"
  }

Hope this helps somebody.

PinoyDev
  • 949
  • 1
  • 10
  • 21
  • This is the way to go if quickly want to extract a value from the appsettings. You can also get a single value, e.g. "BaseAddress": "http://localhost:45492/" in your appsettings.json like so: string baseAddressConfig = configuration.GetValue("BaseAddress"); – Jiren Aug 16 '20 at 11:29
  • 1
    when you talk about time, is dev time or process time? – Leandro Bardelli Sep 22 '20 at 00:16
  • If it does not work just add `using Microsoft.Extensions.Configuration`. I had to add this because I was running my code from UnitTests project. – Tono Nam Mar 08 '22 at 00:06
32

You can also use the configuration directly. Your settings are injected so you can get to them with DI...

private readonly IConfiguration _configuration;

public MyClass(IConfiguration configuration)
{
    _configuration = configuration;
}

and then you can read your settings...

In this case I'm getting a collection back...

var myList = _configuration.GetSection("MyList").Get<List<string>>();
dotNetE
  • 616
  • 1
  • 6
  • 27
Dave Shinkle
  • 932
  • 10
  • 13
  • 5
    @PinoyDev of course it can - it's a constructor, and readonly variables are assignable from constructors – Asunez Jan 09 '19 at 19:30
  • For those who might find this useful: here's a good guide on how to read the JSON configuration: https://www.c-sharpcorner.com/article/reading-values-from-appsettings-json-in-asp-net-core/ – SolidCoder Jun 29 '21 at 13:08
  • its better to take configuration settings through IOptions, as configuration contains a lot of other data, that usually you don't need. – Aliaksei Aksionau Nov 01 '21 at 15:19
8

define your class as

public class MyClass{
   private readonly IConfiguration _configuration;
   public MyClass(IConfiguration configuration)
        {
            _configuration = configuration;
        }
   public void myFunction(){
       var value= _configuration.GetValue("xxx");
}
}

when you call it from anywhere else

IConfiguration config = new ConfigurationBuilder()
                    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: false).Build();
MyClass myclass = new MyClass(config)
michael
  • 83
  • 1
  • 5
3

Addition to answer from @MindingData. I like to map my settings recursively using Configuration.Bind(settings); so that I don't have to add every new section in ConfigureServices.

Example:

appsettings.json:

{
    "MyConfiguration": {
        "MyProperty": true 
    }
}

Settings class, properties must match appsettings.json names:

public class Settings
{

    public MyConfigurationSettings MyConfiguration { get; set; }

    public class MyConfigurationSettings
    {
        public bool MyProperty { get; set; }
    }

}

Startup.cs

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

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

        var settings = new Settings();
        Configuration.Bind(settings);
        services.AddSingleton(settings);
        ...

Can be used in controllers like this:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly Settings _settings;

    public ValuesController(Settings settings)
    {
        _settings = settings;
    }

    [HttpGet("GetValue")]
    public ActionResult<string> Get()
    {
        return Ok(_settings.MyConfiguration.MyProperty);
    }
}
Ogglas
  • 62,132
  • 37
  • 328
  • 418
3

If you already passed to controller your configuration and don't want to map another service in startup configuration, you can easy get your value from configuration in this way:

public Startup(IConfiguration configuration)
{
 Configuration = configuration;
  
 var myProperty = _configuration.GetSection("MyConfiguration")["MyProperty"];
}

using dictionary property.

Enjoy

giorgio calarco
  • 136
  • 1
  • 7
1
  1. Add this in AppSettings.json file
    "Swagger": { "Title": "API DEVELOPMENT" }

  2. Then configure that in Startup.cs file

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
    
    public IConfiguration Configuration { get; }
    
  3. Next get the value from appsettings.json

    var title = Configuration.GetSection("Swagger:Title").Value;
    
  4. Finally put here

    services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = title, Version = "v1" }); }
    
Lukasz Szczygielek
  • 2,768
  • 2
  • 20
  • 34
pintu sharma
  • 171
  • 1
  • 3
0

The top answer of MindingData is great. I just want to add to it, that using IOptions is recommended, because then you can handle the situation when configuration changes and must be reloaded.

For such scenario I suggest using IOptionsMonitor which creates a singleton to store the configuration object and when the appsettings.json is changed, your object will be automatically updated.
You can even register a listener to OnChange() method of IOptionsMonitor and react to the change further.

Using this approach gives you advantage when you have a service in production, that you don't have to restart it to load the new configuration.