431

I have set up my AppSettings data in file appsettings/Config .json like this:

{
  "AppSettings": {
        "token": "1234"
    }
}

I have searched online on how to read AppSettings values from .json file, but I could not get anything useful.

I tried:

var configuration = new Configuration();
var appSettings = configuration.Get("AppSettings"); // null
var token = configuration.Get("token"); // null

I know with ASP.NET 4.0 you can do this:

System.Configuration.ConfigurationManager.AppSettings["token"];

But how do I do this in ASP.NET Core?

one noa
  • 345
  • 1
  • 3
  • 10
Oluwafemi
  • 14,243
  • 11
  • 43
  • 59
  • possible duplicate of [ASP.NET 5 (vNext) - Getting a Configuration Setting](http://stackoverflow.com/questions/30263681/asp-net-5-vnext-getting-a-configuration-setting) – mason Jul 16 '15 at 13:20
  • [A reference MSDN that provides additional insight.](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration?tabs=basicconfiguration) – MDMoore313 Nov 18 '17 at 22:06
  • 6
    @RanadheerReddy, dependency injection works for controllers. But what If someone needs to read a value in Middleware? – Alexander Ryan Baggett Dec 18 '19 at 19:09
  • If you looking for a .net core 6 console app, you may [take a look at this](https://stackoverflow.com/a/70242856/1977871) – VivekDev Sep 27 '22 at 12:57

29 Answers29

474

This has had a few twists and turns. I've modified this answer to be up to date with ASP.NET Core 2.0 (as of 26/02/2018).

This is mostly taken from the official documentation:

To work with settings in your ASP.NET application, it is recommended that you only instantiate a Configuration in your application’s Startup class. Then, use the Options pattern to access individual settings. Let's say we have an appsettings.json file that looks like this:

{
  "MyConfig": {
   "ApplicationName": "MyApp",
   "Version": "1.0.0"
   }

}

And we have a POCO object representing the configuration:

public class MyConfig
{
    public string ApplicationName { get; set; }
    public int Version { get; set; }
}

Now we build the configuration in Startup.cs:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }
}

Note that appsettings.json will be registered by default in .NET Core 2.0. We can also register an appsettings.{Environment}.json config file per environment if needed.

If we want to inject our configuration to our controllers, we'll need to register it with the runtime. We do so via Startup.ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    // Add functionality to inject IOptions<T>
    services.AddOptions();

    // Add our Config object so it can be injected
    services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
}

And we inject it like this:

public class HomeController : Controller
{
    private readonly IOptions<MyConfig> config;

    public HomeController(IOptions<MyConfig> config)
    {
        this.config = config;
    }

    // GET: /<controller>/
    public IActionResult Index() => View(config.Value);
}

The full Startup class:

public class Startup 
{
    public IConfigurationRoot Configuration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

        Configuration = builder.Build();
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();

        // Add functionality to inject IOptions<T>
        services.AddOptions();

        // Add our Config object so it can be injected
        services.Configure<MyConfig>(Configuration.GetSection("MyConfig"));
    }
}
Pranay Aryal
  • 5,208
  • 4
  • 30
  • 41
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • I am getting this compile time error: `Configuration does not contain a definition for 'AddJsonFile'...`. How do I resolve that? – Oluwafemi Jul 16 '15 at 12:09
  • Am getting this error after adding it to project.json: `Dependency Microsoft.Framework.ConfigurationModel.Json >= 1.0.0-alpha4 could not be resolved`. – Oluwafemi Jul 16 '15 at 12:15
  • @Oluwafemi Did you [get the package from nuget](https://www.nuget.org/packages/Microsoft.Framework.ConfigurationModel.Json/)? – Yuval Itzchakov Jul 16 '15 at 12:17
  • 4
    version `"1.0.0-beta4"` works on mine not `"1.0.0-alpha4"`. Thanks a lot! – Oluwafemi Jul 16 '15 at 12:20
  • @Oluwafemi Yes I've updated that to be `beta` as it should. :) – Yuval Itzchakov Jul 16 '15 at 12:21
  • now it gives me InvalidOperationException: Unable to resolve path 'config.json'; construct this IConfigurationSourceRoot with a non-null BasePath. on config.AddJsonFile("config.json"); I need to read AppSettings in a static class instead of controller – dnxit Aug 18 '15 at 20:28
  • @Lucky See [this](https://github.com/aspnet/Announcements/issues/13). Ill update my answer. You'll need `IApplicationEnvironment` to get the base path. – Yuval Itzchakov Aug 18 '15 at 20:32
  • 4
    I need to pass a setting to another layer from a utility class so I need something like this public static string GetConnectionString() { if (string.IsNullOrEmpty(connectionString)) { var builder = new ConfigurationBuilder() .AddJsonFile("config.json"); Configuration = builder.Build(); connectionString = Configuration.Get("Data:DefaultConnection:ConnectionString"); } } return connectionString; } – dnxit Aug 18 '15 at 20:52
  • 1
    And then query the data: var token = configuration.Get("AppSettings:token"); how to instantiate configuration in my utility class ??? – dnxit Aug 18 '15 at 20:57
  • @downvoter I got your flag, I've updated the answer :) – Yuval Itzchakov Sep 15 '16 at 17:30
  • I have created a new `.Net Core` project. It does have `Startup.cs` and `project.json` but there is no `appsetting.json`. It needs to be created manually after the creation of the project or it is created with the project and I have mistakenly deleted it? And if it is to be created manually then where should it be placed? In the same the folder as `project.json`? – phougatv Nov 07 '16 at 16:21
  • `appsetting.json` is just an example. You can have a `barnes.json` file and map it via `AddJsonFile`. – Yuval Itzchakov Nov 07 '16 at 17:00
  • 2
    I get `Argument 2: cannot convert from 'Microsoft.Extensions.Configuration.IConfigurationSection' to 'System.Action<....Settings>'` – Peter Apr 20 '18 at 20:23
  • @Peter Where do you get that? – Yuval Itzchakov Apr 20 '18 at 20:45
  • 1
    @YuvalItzchakov on the following line `.Configure(Configuration.GetSection("Settings"))` – Peter Apr 20 '18 at 20:55
  • 8
    After adding the nuget `Microsoft.Extensions.Options.ConfigurationExtensions` it worked as expected. – Peter Apr 20 '18 at 22:19
  • 11
    this code vs old xml > how many of you have time for this, just to save a string? – Vasil Valchev Sep 28 '18 at 16:00
  • 7
    Nice explanation of the config process logic, but it misses a major point: SetBasePath() and AddJsonFile() are extension methods, berried deeply in the framework in separate assemblies. So in order to get started, one needs to install Microsoft.Extensions.Configuration.FileExtensions and Microsoft.Extensions.Configuration.Json in addition to Microsoft.Extensions.Configuration. – Bozhidar Stoyneff Feb 12 '19 at 09:21
  • @YuvalItzchakov how can I read list of objects rather than object using this? services.Configure>(Configuration.GetSection("MyConfig")); – Prachi Feb 28 '19 at 14:49
  • 1
    This injects `IOptions` in a controller. What if you need to read the settings inside the `ConfigureServices()` method and configure things according to the settings? Is there a way to resolve the settings object manually inside `ConfigureServices()`? – user2173353 Mar 27 '19 at 08:01
  • 1
    Is there a way to get only the settings for a specific ConfigurationProvider? – ryanwebjackson Apr 10 '19 at 17:02
  • @YuvalItzchakov I think you could add to your answer a tip: if your `class name != key section` from appsetting configuration then it won't be mapped automatically. Unless you will add Bind(option). So it would be `services.Configure(options=> Configuration.GetSection("MyConfig").Bind(options));`. I'm shocked that nobody has mentioned it yet. – DiPix Oct 09 '19 at 08:40
  • What if you want to use in Middleware instead of the controller? E.G. I am caching http responses in Redis and want to grab the connection string to use for Redis. – Alexander Ryan Baggett Dec 18 '19 at 19:01
  • 1
    How would this work without MVC, but a with standard public class, that is called else where? – Greg Apr 15 '20 at 22:53
  • 64
    Absolutely incredible how convoluted it is just to retrieve an application setting. – The Muffin Man May 24 '20 at 21:34
  • 3
    You didn't show how you retrieved the value it self from the code – c-sharp-and-swiftui-devni Jul 24 '20 at 21:56
  • Suppose in the dev json file I created key called `key1` and in prod json file I create key called `key2`, then when I run the project in visual studio, it is reading both the keys. Shouldn't it read only the key from the dev json file? – variable Jan 12 '22 at 10:36
  • 1
    @TheMuffinMan - right? Developers seem to get bored with tech and basically make it more complex than it needs to be as a way to contrive something to be interested in. I think of TypeScript and Angular in the same way - garbage piles of complexity that ultimately cause far more work than necessary. At least, that's what the voices tell me. – Jason Bunting Mar 01 '22 at 17:25
  • @JasonBunting I really like TypeScript in the spirit of making javascript dev better, but it falls short of C# in some ways. I think all we really wanted was C# syntax for the browser haha. – The Muffin Man Mar 16 '22 at 22:45
  • @TheMuffinMan - to each their own! I never thought JavaScript dev needed the help, but I am aware that opinion makes me an outlier. :) Have a great day! – Jason Bunting Apr 04 '22 at 18:05
  • Designed by MS devs with next to zero practical experience of working in a real commercial environment and are experts at making simple things unnecessarily over complicated. – Mark Worrall May 31 '22 at 15:31
  • 1
    It would be interesting to hear from somebody who worked on the team why they made the choice to purposefully make it so much more difficult to work with. Config was always brain-dead simple prior to appsettings.json - it can only be a conscious choice. To weed out some folks for some reason? – Chris B. Behrens Sep 02 '22 at 18:26
  • 1
    @ChrisB.Behrens It just makes everything a lot easier to tests afterwards, you can just mock `IOptions` for anywhere you need some data related to the configuration. The configurationmanager itself was a lot harder to test properly – Icepickle Sep 19 '22 at 09:36
154

.NET Core 3.0 / .NET 6

This is a sleek and simple solution.

File appsettings.json

{
    "ConnectionStrings": {
        "DefaultConnection": "****;"
    },
    "AppSettings": {
        "APP_Name": "MY_Service",
        "SampleIntValue": 100
    }
}

Controller:

On top:

using Microsoft.Extensions.Configuration;

In your code:

VAR 1:

var AppName = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build().GetSection("AppSettings")["APP_Name"];

or

VAR 2: (For reading multiple values or numbers)

var MyConfig = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();
    var IntExample = MyConfig.GetValue<int>("AppSettings:SampleIntValue");
    var AppName = MyConfig.GetValue<string>("AppSettings:APP_Name");
Alexander S.
  • 1,971
  • 2
  • 14
  • 22
  • 15
    @Essej: You need to install the Microsoft.Extensions.Configuration.Json nuget package in order to use the AddJsonFile methode. – Baccata Jul 03 '20 at 11:21
  • 5
    The only method I've found that works in a .Net Core Program.cs file. Have to agree with a comment on a different answer: so much convolution just to get a settings file. – MBielski Jan 04 '22 at 22:47
  • 1
    OMG thank you for this! The missing piece that none of the others provided was how to access the settings, e.g. ```.GetSection("AppSettings")["APP_Name"]``` – Steve Silberberg Feb 22 '22 at 14:05
  • sidestepping the application host framework is sometimes the best way to go, for some simple console applications for example, thanks for the answer – fartwhif May 12 '22 at 15:28
  • 5
    Finally a simple solution, thanks. WHY has msft made this so difficult in Core?? – Moby's Stunt Double Jul 10 '22 at 00:25
  • To use the GetValue extension method, you also need to install the Microsoft.Extensions.Configuration.Bindings nuget package. Otherwise, this solution continues to work with .NET 6.0. While not the point of the example, use Generics to easily test that a value was read and you're not just getting the default value for the type. – Goal Man Sep 13 '22 at 15:10
  • @Moby'sStuntDouble doesn't suprise, their business model requires them to constantly reinvent the wheel. I am personally moving to .ini files and away from .json settings to save time in the long run. – TheLegendaryCopyCoder Sep 29 '22 at 09:33
  • Works for me; I found that all the other solutions which don't explicitly call `AddJsonFile()` will return values from the copy of appsettings.json in the project folder -- ignoring any modifications to appsettings.json in the runtime folder! – M.M Nov 10 '22 at 03:26
  • This is not VERY cumbersome, but still seems unnecessarily cumbersome. .NET's `Host` has already loaded `appsettings.json` for its own use (like logging levels), right? Then, why isn't there a simpler way like `var host = Host.CreateDefaultBuilder() .... .Build(); host.Configuration["AppSettings:SampleIntValue"]`, because that thing exists for `WebApplication`? – Damn Vegetables Nov 22 '22 at 14:13
78

First off: The assembly name and namespace of Microsoft.Framework.ConfigurationModel has changed to Microsoft.Framework.Configuration. So you should use: e.g.

"Microsoft.Framework.Configuration.Json": "1.0.0-beta7"

as a dependency in project.json. Use beta5 or 6 if you don't have 7 installed. Then you can do something like this in Startup.cs.

public IConfiguration Configuration { get; set; }

public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
{
     var configurationBuilder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
        .AddJsonFile("config.json")
        .AddEnvironmentVariables();
     Configuration = configurationBuilder.Build();
}

If you then want to retrieve a variable from the config.json you can get it right away using:

public void Configure(IApplicationBuilder app)
{
    // Add .Value to get the token string
    var token = Configuration.GetSection("AppSettings:token");
    app.Run(async (context) =>
    {
        await context.Response.WriteAsync("This is a token with key (" + token.Key + ") " + token.Value);
    });
}

or you can create a class called AppSettings like this:

public class AppSettings
{
    public string token { get; set; }
}

and configure the services like this:

public void ConfigureServices(IServiceCollection services)
{       
    services.AddMvc();

    services.Configure<MvcOptions>(options =>
    {
        //mvc options
    });

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

and then access it through e.g. a controller like this:

public class HomeController : Controller
{
    private string _token;

    public HomeController(IOptions<AppSettings> settings)
    {
        _token = settings.Options.token;
    }
}
meJustAndrew
  • 6,011
  • 8
  • 50
  • 76
hug
  • 1,169
  • 10
  • 7
  • can you please share configuration json for "AppSettings" for reference – Ankit Mori May 02 '18 at 13:18
  • I need entire appSettings.json configs in class, for this, I have designed class as per JSON and use `Configuration.Get()` to deserialize entire file instead of a specific section. – Nilay Mehta Jul 31 '18 at 01:06
69

For .NET Core 2.0, things have changed a little bit. The startup constructor takes a Configuration object as a parameter, So using the ConfigurationBuilder is not required. Here is mine:

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)
{
    services.Configure<StorageOptions>(Configuration.GetSection("AzureStorageConfig"));
}

My POCO is the StorageOptions object mentioned at the top:

namespace FictionalWebApp.Models
{
    public class StorageOptions
    {
        public String StorageConnectionString { get; set; }
        public String AccountName { get; set; }
        public String AccountKey { get; set; }
        public String DefaultEndpointsProtocol { get; set; }
        public String EndpointSuffix { get; set; }

        public StorageOptions() { }
    }
}

And the configuration is actually a subsection of my appsettings.json file, named AzureStorageConfig:

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=fictionalwebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },

  "AzureStorageConfig": {
    "AccountName": "fictionalwebapp",
    "AccountKey": "Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==",
    "DefaultEndpointsProtocol": "https",
    "EndpointSuffix": "core.windows.net",
    "StorageConnectionString": "DefaultEndpointsProtocol=https;AccountName=fictionalwebapp;AccountKey=Cng4Afwlk242-23=-_d2ksa69*2xM0jLUUxoAw==;EndpointSuffix=core.windows.net"
  }
}

The only thing I'll add is that, since the constructor has changed, I haven't tested whether something extra needs to be done for it to load appsettings.<environmentname>.json as opposed to appsettings.json.

MDMoore313
  • 3,233
  • 1
  • 23
  • 38
  • Just a note that you still need to toss .AddJsonFile("yourfile.json") to ConfigConfiguration. IE, you need to tell it where the file is. Didn't see that in the answer. – Eric Mar 12 '18 at 17:06
  • Eric I will retest that, I don't remember adding that line; Could it be necessary only if the name of the json file isn't the default name? – MDMoore313 Mar 12 '18 at 17:31
  • Per MSDN, it is not required for ASPNETCORE 2.0, although it doesnt appear to work for me either. https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.webhost.createdefaultbuilder?view=aspnetcore-2.0#Microsoft_AspNetCore_WebHost_CreateDefaultBuilder – Sat Thiru Mar 26 '18 at 04:47
  • 1
    I can confirm that I had to build a ConfigurationBuilder() object and call AddJSONFile() to load the appSettings.json files into the config dictionary. This is ASP.NET Core 2.0. Is this a bug as it runs contrary to what MSDN says? – Sat Thiru Mar 26 '18 at 05:05
  • 1
    Can you give an example how you inject StorageOptions into your controllers? If I use hug's approach of using dependency injection with `public HomeController(IOptions settings)`, I get this error message: Model bound complex types must not be abstract or value types and must have a parameterless constructor. – Jpsy May 03 '18 at 09:21
  • Can configure for a list of StorageOptions? Like services.Configure>. I got an error. – Thang Pham Jun 06 '18 at 04:05
  • @Jpsy Usually I use the example from MS, `public class SettingsController : Controller { private readonly SampleWebSettings _settings; public SettingsController(IOptions settingsOptions) { _settings = settingsOptions.Value; } }` – MDMoore313 Dec 16 '20 at 14:33
56

With .NET Core 2.2, and in the simplest way possible...

public IActionResult Index([FromServices] IConfiguration config)
{
    var myValue = config.GetValue<string>("MyKey");
}

appsettings.json is automatically loaded and available through either constructor or action injection, and there's a GetSection method on IConfiguration as well. There isn't any need to alter Startup.cs or Program.cs if all you need is appsettings.json.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
tnJed
  • 838
  • 9
  • 12
  • 6
    even simpler: `var myValue = config["MyKey"]` – jokab Oct 29 '19 at 00:36
  • 3
    ... and you can do: config["Storage:ConnectionString"] to get elements inside the json. I can confirm this technique works on .net core 3 and works on construction injection. – Mário Meyrelles Jan 20 '20 at 04:06
42

If you just want to get the value of the token then use

Configuration["AppSettings:token"]

kodebot
  • 1,718
  • 1
  • 22
  • 29
24

I doubt this is good practice but it's working locally. I'll update this if it fails when I publish/deploy (to an IIS web service).

Step 1 - Add this assembly to the top of your class (in my case, controller class):

using Microsoft.Extensions.Configuration;

Step 2 - Add this or something like it:

var config = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json").Build();

Step 3 - Call your key's value by doing this (returns string):

config["NameOfYourKey"]
T.S.
  • 18,195
  • 11
  • 58
  • 78
Eric Milliot-Martinez
  • 4,076
  • 3
  • 23
  • 28
21

For ASP.NET Core 3.1 you can follow this documentation:

https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1

When you create a new ASP.NET Core 3.1 project or .NET 5 project you will have the following configuration line in Program.cs:

Host.CreateDefaultBuilder(args)

This enables the following:

  1. ChainedConfigurationProvider : Adds an existing IConfiguration as a source. In the default configuration case, adds the host configuration and setting it as the first source for the app configuration.
  2. appsettings.json using the JSON configuration provider.
  3. appsettings.Environment.json using the JSON configuration provider. For example, appsettings.Production.json and appsettings.Development.json.
  4. App secrets when the app runs in the Development environment.
  5. Environment variables using the Environment Variables configuration provider.
  6. Command-line arguments using the Command-line configuration provider.

This means you can inject IConfiguration and fetch values with a string key, even nested values. Like IConfiguration ["Parent:Child"];

Example:

appsettings.json

{
  "ApplicationInsights":
    {
        "Instrumentationkey":"putrealikeyhere"
    }
}

WeatherForecast.cs

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;
    private readonly IConfiguration _configuration;

    public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
    {
        _logger = logger;
        _configuration = configuration;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var key = _configuration["ApplicationInsights:InstrumentationKey"];

        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}
Ogglas
  • 62,132
  • 37
  • 328
  • 418
  • 2
    @Ogglas...how the caller of WeatherForecastController() could obtain the class that implements IConfiguration? – Johnny Wu Jun 21 '20 at 17:28
  • This worked for me on net 6, yet i didnt find the Host.CreateDefaultBuilder(args) on program.cs the program.cs has var builder = WebApplication.CreateBuilder(args); that assume has the same functionality, cause the rest works – cabaji99 Aug 29 '22 at 16:41
20

This worked for me .Net 5/6

I have a appsettings.development.json file. I have "Development" environment selected that's why I have settings in my development.json file. You can use appsettings.josn with default environment.

enter image description here

with this configuration

enter image description here

created a class with config properties

enter image description here

Registered my calls in Startup

enter image description here

I can now access in my controller

enter image description here

Ali
  • 1,015
  • 14
  • 40
  • Can we decorate the model property with JsonProperty (Name will be similar to the appsettings one but not the property name) ? – ravithejag May 18 '21 at 13:00
  • not sure, never tried. you can try and update me. – Ali May 19 '21 at 10:52
  • 1
    I tried, no luck in finding the solution. I have modified the appsettings keys itself to align with my project needs – ravithejag May 24 '21 at 13:40
  • 1
    Hey just wanted to say thanks for a well thought out and thorough explanation, this really helped me – d0rf47 May 13 '22 at 13:58
16

The following works for console applications;

  1. Install the following NuGet packages (.csproj);

    <ItemGroup>
        <PackageReference Include="Microsoft.Extensions.Configuration" Version="2.2.0-preview2-35157" />
        <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0-preview2-35157" />
        <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0-preview2-35157" />
    </ItemGroup>
    
  2. Create appsettings.json at root level. Right click on it and "Copy to Output Directory" as "Copy if newer".

  3. Sample configuration file:

    {
      "AppConfig": {
        "FilePath": "C:\\temp\\logs\\output.txt"
      }
    }
    
  4. Program.cs

    configurationSection.Key and configurationSection.Value will have config properties.

    static void Main(string[] args)
    {
        try
        {
    
            IConfigurationBuilder builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
    
            IConfigurationRoot configuration = builder.Build();
            // configurationSection.Key => FilePath
            // configurationSection.Value => C:\\temp\\logs\\output.txt
            IConfigurationSection configurationSection = configuration.GetSection("AppConfig").GetSection("FilePath");
    
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }
    
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Teoman shipahi
  • 47,454
  • 15
  • 134
  • 158
13

Here's the full use-case for ASP.NET Core!

articles.json

{
  "shownArticlesCount": 3,
  "articles": [
    {
      "title": "My Title 1",
      "thumbnailLink": "example.com/img1.png",
      "authorProfileLink": "example.com/@@alper",
      "authorName": "Alper Ebicoglu",
      "publishDate": "2018-04-17",
      "text": "...",
      "link": "..."
    },
    {
      "title": "My Title 2",
      "thumbnailLink": "example.com/img2.png",
      "authorProfileLink": "example.com/@@alper",
      "authorName": "Alper Ebicoglu",
      "publishDate": "2018-04-17",
      "text": "...",
      "link": "..."
    },
  ]
}

ArticleContainer.cs

public class ArticleContainer
{
    public int ShownArticlesCount { get; set; }

    public List<Article> Articles { get; set; }
}

public class Article
{
    public string Title { get; set; }

    public string ThumbnailLink { get; set; }

    public string AuthorName { get; set; }

    public string AuthorProfileLink { get; set; }

    public DateTime PublishDate { get; set; }

    public string Text { get; set; }

    public string Link { get; set; } 
}

Startup.cs

public class Startup
{
    public IConfigurationRoot ArticleConfiguration { get; set; }

    public Startup(IHostingEnvironment env)
    {
        ArticleConfiguration = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("articles.json")
            .Build();
    }

    public IServiceProvider ConfigureServices(IServiceCollection services)
    {
        services.AddOptions();

        services.Configure<ArticleContainer>(ArticleConfiguration);
    }
}

Index.cshtml.cs

public class IndexModel : PageModel
{
    public ArticleContainer ArticleContainer { get;set; }

    private readonly IOptions<ArticleContainer> _articleContainer;

    public IndexModel(IOptions<ArticleContainer> articleContainer)
    {
        _articleContainer = articleContainer;
    }

    public void OnGet()
    {
        ArticleContainer = _articleContainer.Value;
    }
}

Index.cshtml.cs

<h1>@Model.ArticleContainer.ShownArticlesCount</h1>
Alper Ebicoglu
  • 8,884
  • 1
  • 49
  • 55
11

For .NET Core 2.0, you can simply:

Declare your key/value pairs in appsettings.json:

{
  "MyKey": "MyValue"
}

Inject the configuration service in startup.cs, and get the value using the service

using Microsoft.Extensions.Configuration;

public class Startup
{
    public void Configure(IConfiguration configuration,
                          ... other injected services
                          )
    {
        app.Run(async (context) =>
        {
            string myValue = configuration["MyKey"];
            await context.Response.WriteAsync(myValue);
        });
Christian
  • 3,708
  • 3
  • 39
  • 60
Chris Halcrow
  • 28,994
  • 18
  • 176
  • 206
11

Super late to the party but if someone finds this out.

You can call IConfiguration from Microsoft.Extensions.Configuration;

public static IConfiguration Configuration { get; }
public static string MyAwesomeString = Configuration.GetSection("appSettings")["MyAwesomeString"].ToString();
Napal
  • 286
  • 2
  • 9
9

Just to complement the Yuval Itzchakov answer.

You can load configuration without builder function, you can just inject it.

public IConfiguration Configuration { get; set; }

public Startup(IConfiguration configuration)
{
   Configuration = configuration;
}
Tiago Barroso
  • 329
  • 4
  • 4
8

.NET Core 2.1.0

  1. Create the .json file on the root directory
  2. On your code:
var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); 
var config = builder.Build();

3. Install the following dependencies:

Microsoft.Extensions.Configuration
Microsoft.Extensions.Configuration.json

4. Then, IMPORTANT: Right-click on the appsettings.json file -> click on Properties -> select Copy if newer: enter image description here

  1. Finally, you can do:

    config["key1"]

Considering that my config file will look like this:

{
    "ConnectionStrings": "myconnection string here",
    "key1": "value here"
}
Gregory
  • 6,514
  • 4
  • 28
  • 26
8

For ASP.NET Core 6.0 you can simply:

appsetting.json

{
  "AppSettings": {
        "Token": "1234"
    }
}

TestModel.cs

using Microsoft.Extensions.Configuration

public class TestModel : PageModel
{
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myToken = Configuration["AppSettings:Token"];        
        return Content($"myToken value: {myToken}");
    }
}
Juan Carlos Ibarra
  • 1,299
  • 14
  • 15
7

They just keep changing things – having just updated Visual Studio and had the whole project bomb, on the road to recovery and the new way looks like this:

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

    if (env.IsDevelopment())
    {
        // For more details on using the user secret store see http://go.microsoft.com/fwlink/?LinkID=532709
        builder.AddUserSecrets();
    }

    builder.AddEnvironmentVariables();
    Configuration = builder.Build();
}

I kept missing this line!

.SetBasePath(env.ContentRootPath)
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Monolithcode
  • 598
  • 8
  • 19
  • 1
    How can we get the AppSettings values in Test Projects using the same approach? – S.Siva Sep 30 '16 at 10:40
  • 3
    `They just keep changing things`. This. Almost every answer on this page only applies to a specific version of .Net Core. – Steve Smith Oct 16 '19 at 11:40
7

In addition to existing answers I'd like to mention that sometimes it might be useful to have extension methods for IConfiguration for simplicity's sake.

I keep JWT config in appsettings.json so my extension methods class looks as follows:

public static class ConfigurationExtensions
{
    public static string GetIssuerSigningKey(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:SecurityKey");
        return result;
    }

    public static string GetValidIssuer(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:Issuer");
        return result;
    }

    public static string GetValidAudience(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Authentication:JwtBearer:Audience");
        return result;
    }

    public static string GetDefaultPolicy(this IConfiguration configuration)
    {
        string result = configuration.GetValue<string>("Policies:Default");
        return result;
    }

    public static SymmetricSecurityKey GetSymmetricSecurityKey(this IConfiguration configuration)
    {
        var issuerSigningKey = configuration.GetIssuerSigningKey();
        var data = Encoding.UTF8.GetBytes(issuerSigningKey);
        var result = new SymmetricSecurityKey(data);
        return result;
    }

    public static string[] GetCorsOrigins(this IConfiguration configuration)
    {
        string[] result =
            configuration.GetValue<string>("App:CorsOrigins")
            .Split(",", StringSplitOptions.RemoveEmptyEntries)
            .ToArray();

        return result;
    }
}

It saves you a lot of lines and you just write clean and minimal code:

...
x.TokenValidationParameters = new TokenValidationParameters()
{
    ValidateIssuerSigningKey = true,
    ValidateLifetime = true,
    IssuerSigningKey = _configuration.GetSymmetricSecurityKey(),
    ValidAudience = _configuration.GetValidAudience(),
    ValidIssuer = _configuration.GetValidIssuer()
};

It's also possible to register IConfiguration instance as singleton and inject it wherever you need - I use Autofac container here's how you do it:

var appConfiguration = AppConfigurations.Get(WebContentDirectoryFinder.CalculateContentRootFolder());
builder.Register(c => appConfiguration).As<IConfigurationRoot>().SingleInstance();

You can do the same with MS Dependency Injection:

services.AddSingleton<IConfigurationRoot>(appConfiguration);
Alex Herman
  • 2,708
  • 4
  • 32
  • 53
6
private readonly ILogger<WeatherForecastController> _logger;

private IConfiguration _configuration;

public WeatherForecastController(ILogger<WeatherForecastController> logger, IConfiguration configuration)
{
    _logger = logger;

    _configuration = configuration;
}

[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
    //You can use any of these

    var db = _configuration.GetSection("ConnectionStrings").GetSection("BookStoresDB2").Value;

    var db1 = _configuration["ConnectionStrings:BookStoresDB2"];

    var db2 = _configuration.GetValue<string>("ConnectionStrings:BookStoresDB2");
}
Md Shahriar
  • 2,072
  • 22
  • 11
5

The .NET Core 2.2 way

(No doubt Microsoft will change it again to something completely different in the next .NET version.)

1. appSettings.json

It may look something like this. Here we will be loading Setting1 and Setting2

{
  "Logging": {
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Setting1": "abc",
  "Setting2": 123
}

2. AppSettings.cs

The POCO class to hold Setting1 and Setting2. We will be loading the appsettings.json into this class object. The structure of the POCO class should match the JSON file, properties may be nested within other properties/classes if desired.

public class AppSettings
{
    public string Setting1 { get; set; }
    public int Setting2 { get; set; }
}

3 Startup.cs

Load appSettings.json into you AppSettings object and start using it:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        AppSettings settings = new AppSettings();

        Configuration = configuration;
        configuration.Bind(settings);

        // Now start using it
        string setting1 = settings.Setting1;
        int setting2 = settings.Setting2;
    }
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
CodeMonkey
  • 629
  • 7
  • 16
  • 1
    A combination of `new ConfigurationBuilder()...Build()` and `config.Bind(appSettings)` did it for me, thanks – Pierre Oct 30 '20 at 12:14
4

Get it inside controller as an object via call Get<YourType>():

public IActionResult Index([FromServices] IConfiguration config)
{
    BillModel model = config.GetSection("Yst.Requisites").Get<BillModel>();
    return View(model);
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lapenkov Vladimir
  • 3,066
  • 5
  • 26
  • 37
4

You can simply use...

var configurations = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

var db3 = configurations["ConnectionStrings:BookStoresDB2"];
Blastfurnace
  • 18,411
  • 56
  • 55
  • 70
Md Shahriar
  • 2,072
  • 22
  • 11
3

First you should inject IConfiguration and then for reading from appsettings, you can use one of this methods:

  1. Get a section data

    var redisConfig = configuration.GetSection("RedisConfig");
    
  2. Get a value within a section

    var redisServer = configuration.GetValue<string>("RedisConfig:ServerName");
    
  3. Get nested value within section

    var redisExpireMInutes = configuration.GetValue<int>("RedisConfig:ServerName:ExpireMInutes");
    
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hamed Naeemaei
  • 8,052
  • 3
  • 37
  • 46
  • Injecting works for controllers, but what if I want to use it in Middleware like [here](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/middleware/write?view=aspnetcore-3.1)? E.G. I am using Redis as middleware to cache http responses. – Alexander Ryan Baggett Dec 18 '19 at 19:06
2

Was this "cheating"? I just made my Configuration in the Startup class static, and then I can access it from anywhere else:

public class Startup
{
    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
    public Startup(IHostingEnvironment env)
    {
        var builder = new ConfigurationBuilder()
            .SetBasePath(env.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
            .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
            .AddEnvironmentVariables();

        Configuration = builder.Build();
    }

    public static IConfiguration Configuration { get; set; }
  • 1
    I know this is old, yet people are still reading it. This is not a good practice. This creates a direct reference to a part of your code instead of using DI to load it up, in time when you create a map of your code there will be too many places pointing to your code and you will have to refactor. – cpoDesign May 05 '21 at 21:28
  • Why "a direct reference to my code" is bad? DI is overengeneering a simple task. – Alex from Jitbit Aug 26 '21 at 08:40
2

Using .NET 7 with everything in Program.cs

var token = builder.Configuration["AppSettings:token"]
Nomnom
  • 4,193
  • 7
  • 27
  • 37
0

You can try below code. This is working for me.

public class Settings
{
    private static IHttpContextAccessor _HttpContextAccessor;

    public Settings(IHttpContextAccessor httpContextAccessor)
    {
        _HttpContextAccessor = httpContextAccessor;
    }

    public static void Configure(IHttpContextAccessor httpContextAccessor)
    {
        _HttpContextAccessor = httpContextAccessor;
    }

    public static IConfigurationBuilder Getbuilder()
    {
        var builder = new ConfigurationBuilder()
          .SetBasePath(Directory.GetCurrentDirectory())
          .AddJsonFile("appsettings.json");
        return builder;
    }

    public static string GetAppSetting(string key)
    {
        //return Convert.ToString(ConfigurationManager.AppSettings[key]);
        var builder = Getbuilder();
        var GetAppStringData = builder.Build().GetValue<string>("AppSettings:" + key);
        return GetAppStringData;
    }

    public static string GetConnectionString(string key="DefaultName")
    {
        var builder = Getbuilder();
        var ConnectionString = builder.Build().GetValue<string>("ConnectionStrings:"+key);
        return ConnectionString;
    }
}

Here I have created one class to get connection string and app settings.

I Startup.cs file you need to register class as below.

public class Startup
{

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
        Settings.Configure(httpContextAccessor);
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jishan siddique
  • 1,848
  • 2
  • 12
  • 23
0

In addition to Ali's answer, you have to inject the IConfiguration object in constructor:

appsettings.js

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "AppSettings": {
      "ServerUrl": "some url"
  }
  
}

Define AppSettings class

    public class AppSettings
    {
        public string ServerUrl { get; set; }
    }

Startup.cs

 public class Startup
    {
        private readonly IConfiguration Configuration;
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
            services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            ...
        }
    }

Controller

    [Route("api/[controller]")]
    [ApiController]
    public class AuthenticationController : ControllerBase
    {
        private readonly AppSettings config;

        public AuthenticationController (IOptions<AppSettings> config)
        {
            this.config= config.Value;
        }

        [HttpGet("token")]

        public ActionResult Token()
        {
          var server=config.ServerUrl;

        }

Works for .NET 5

The One
  • 4,560
  • 5
  • 36
  • 52
0

To get settings data in .Net 6, I use the IConfiguration interface with some abstraction added to help me test it in my projects, making my code more flexible.

For example, there is some API Url in the appsettings.json file:

"ApiBaseUri": "https://dev.api.com/"

To minimize the cost of changing the code due to the fact that the mechanism for working with configs will be changed in the next version of the .Net Core framework, I use a wrapper for the IConfiguration interface.

public interface IConfigurationWrapper
{
    string? GetSectionValue(string key);
}

public class ConfigurationWrapper : IConfigurationWrapper
{
    private readonly IConfiguration _config;

    public ConfigurationWrapper(IConfiguration config)
    {
        _config = config;
    }

    public string? GetSectionValue(string key)
    {
        return _config.GetSection(key).Value;
    }
}

And finally there is a special interface to represent the settings in the config file:

public interface IAppSettings
{
    Uri? GetApiBaseUri();
}

public class AppSettings : IAppSettings
{
    private const string ApiBaseUriSettingName = "ApiBaseUri";

    private readonly IConfigurationWrapper _config;

    public AppSettings(IConfigurationWrapper config)
    {
        _config = config;
    }

    public Uri? GetApiBaseUri()
    {
        string uriValue = _config.GetSectionValue(ApiBaseUriSettingName);

        return string.IsNullOrEmpty(uriValue) ? null : new Uri(uriValue);
    }
}

And that's how I use it in my code:

public class MyService : IMyService
{
    private readonly IAppSettings _settings;

    private readonly IRestRequestFactory _requestFactory;
    private readonly IRestResponseFactory _responseFactory;

    public MyService(IAppSettings settings, IRestRequestFactory requestFactory, IRestResponseFactory responseFactory)
    {
        _settings = settings;
        _requestFactory = requestFactory;
        _responseFactory = responseFactory;
    }

    public async Task<decimal?> GetSomeEndpointResponseAsync(FilterModel filter, CancellationToken token)
    {
        var request = _requestFactory.CreatePostRequest(ApiUrls.SomeEndpoint, filter);

        var response = await _responseFactory.GetRestResponseAsync<ResponseResultModel<decimal?>>(request, _settings.GetApiBaseUri(), token);

        return response.Data?.Data;
    }
}

And I also can easily cover my AppSettings with unit tests:

[TestFixture]
public class AppSettingsTests
{
    private Mock<IConfigurationWrapper> _configurationMock;

    private IAppSettings _settings;

    [SetUp]
    public void SetUp()
    {
        _configurationMock = new Mock<IConfigurationWrapper>();

        _settings = new AppSettings(_configurationMock.Object);
    }

    [Test]
    public void GetApiBaseUri_ApiBaseUriIsEmptyString_ReturnsNull()
    {
        // Arrange
        string uri = string.Empty;

        _configurationMock.Setup(m => m.GetSectionValue(It.IsAny<string>())).Returns(uri);

        // Act
        Uri? result = _settings.GetApiBaseUri();

        // Assert
        Assert.IsNull(result);
    }

    [Test]
    public void GetApiBaseUri_ApiBaseUriIsNull_ReturnsNull()
    {
        // Arrange
        string uri = null;

        _configurationMock.Setup(m => m.GetSectionValue(It.IsAny<string>())).Returns(uri);

        // Act
        Uri? result = _settings.GetApiBaseUri();

        // Assert
        Assert.IsNull(result);
    }
}

Hope this helps.

Denis Kiryanov
  • 451
  • 3
  • 9
-3

With the latest iteration of netcoreapp 3.1 out, you can do this pretty simply without any third-party dependencies.

I created a gist for this, but you can use this class to read a JSON file and return dynamic properties.

using System.Text.Json;
using System.IO;

class ConfigurationLoader
{

    private dynamic configJsonData;
    public ConfigurationLoader Load(string configFilePath = "appsettings.json")
    {
        var appSettings = File.ReadAllText(configFilePath);
        this.configJsonData = JsonSerializer.Deserialize(appSettings, typeof(object));
        return this;
    }

    public dynamic GetProperty(string key)
    {
        var properties = key.Split(".");
        dynamic property = this.configJsonData;
        foreach (var prop in properties)
        {
            property = property.GetProperty(prop);
        }

        return property;
    }
}

I specifically made this so I could use an appconfig.json in my dotnet console application. I just put this in my Program.Main function:

var config = new ConfigurationLoader();
config.Load();
Console.WriteLine(config.GetProperty("Environment.Name"));

And this will return a dynamic object for the property. (A JsonElement if it's not a primitive). My appsettings.json file looks like this:

{
  "Environment": {
    "Token": "abc-123",
    "Name": "Production"
  }
}
Justin Gilman
  • 479
  • 4
  • 12
  • 1
    You shouldn't create custom code for something that is built into .NET Core. You're reinventing a worse wheel. – Kellen Stuart Sep 20 '21 at 15:21
  • I appreciate your constructive criticism @kellen-stuart . When I had this issue, I was unable to find something built into .NET Core to load appsettings for my console app. Could you point me to the appropriate resource so I can update my solution? – Justin Gilman Sep 21 '21 at 17:56
  • 1
    Using the `ConfigurationBuilder` is the correct way; there's a method called `AddJsonFile` https://learn.microsoft.com/en-us/dotnet/api/microsoft.extensions.configuration.configurationbuilder?view=dotnet-plat-ext-5.0 – Kellen Stuart Sep 22 '21 at 18:54