DEV Community ๐Ÿ‘ฉโ€๐Ÿ’ป๐Ÿ‘จโ€๐Ÿ’ป

Masui Masanori
Masui Masanori

Posted on

[ASP.NET Core] Get values from IConfiguration

Intro

I usually just add string values into config files.
But when I added some other type values, I couldn't get them.

So I try getting values from "appsettings.Development.json" in this time.

Environments

  • .NET ver.6.0.102
  • NLog.Web.AspNetCore ver.4.14.0

Sample Project

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}
Enter fullscreen mode Exit fullscreen mode

appsettings.Development.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Debug",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "SampleText": "Hello",
  "SampleNumber": 3,
  "SampleBoolean": true,
  "SampleArray": ["Hello", "World"],
  "SampleBook": { "id": 5, "name": "Sample"},
  "SampleBooks": [{ "Id": 6, "Name": "Sample1"},
    { "Id": 7, "Name": "Sample2"}],
  "NullSample": null
}
Enter fullscreen mode Exit fullscreen mode

Program.cs

using NLog.Web;

var logger = NLogBuilder.ConfigureNLog("Nlog.config").GetCurrentClassLogger();
try 
{
    var builder = WebApplication.CreateBuilder(args);
    builder.Host.ConfigureLogging(logging =>
    {
        logging.ClearProviders();
        logging.AddConsole();
    })
    .UseNLog();
    builder.Services.AddControllers();

    var app = builder.Build();
    app.UseRouting();
    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
    app.Run();
}
catch(Exception ex)
{
    logger.Error(ex, "Stopped program because of exception");
}
finally
{
    NLog.LogManager.Shutdown();
}
Enter fullscreen mode Exit fullscreen mode

Book.cs

namespace ConfigSample.Books.Models;

public record Book
{
    public int Id { get; init; }
    public string Name { get; init; } = "";
}
Enter fullscreen mode Exit fullscreen mode

HomeController.cs

using ConfigSample.Books.Models;
using Microsoft.AspNetCore.Mvc;

namespace ConfigSample.Controllers;

public class HomeController: Controller
{
    private readonly ILogger<HomeController> logger;
    private readonly IConfiguration config;
    public HomeController(ILogger<HomeController> logger,
        IConfiguration config)
    {
        this.logger = logger;
        this.config = config;
    }
    [Route("")]
    public string Index()
    {
        // get values and log them here.

        return "Hello World";
    }
}
Enter fullscreen mode Exit fullscreen mode

Getting primitive type values

In JSON, I can use string, number, boolean, array, object, and null.
Among them, I can get string, number, boolean values with very simple way.

HomeController.cs

...
    [Route("")]
    public string Index()
    {
        // get values and log them here.
        this.logger.LogDebug(this.config["SampleText"]);
        this.logger.LogDebug(this.config["SampleNumber"]);
        this.logger.LogDebug(this.config["SampleBoolean"]);
        this.logger.LogDebug(this.config["NullSample"]);
        return "Hello World";
    }
...
Enter fullscreen mode Exit fullscreen mode

Result

dbug: ConfigSample.Controllers.HomeController[0]
      Hello
2022-02-21 01:28:32.2159||DEBUG|ConfigSample.Controllers.HomeController|Hello
dbug: ConfigSample.Controllers.HomeController[0]
      3
2022-02-21 01:28:32.2342||DEBUG|ConfigSample.Controllers.HomeController|3
dbug: ConfigSample.Controllers.HomeController[0]
      True
2022-02-21 01:28:32.2342||DEBUG|ConfigSample.Controllers.HomeController|True
dbug: ConfigSample.Controllers.HomeController[0]
2022-02-21 01:28:32.2342||DEBUG|ConfigSample.Controllers.HomeController|

Enter fullscreen mode Exit fullscreen mode

Null values are as same as the values what are not found?

No.

When I set value as null, I wil get empty values from IConfiguration.
But when the key isn't found, I will get null.

HomeController.cs

...
    [Route("")]
    public string Index()
    {
...
        // key:SampleText1 isn't found in appsettings.json and appsettings.Development.json
        var notFound = this.config["SampleText1"];
        this.logger.LogDebug($"NotFound Null?:{(notFound == null)} Empty:{(notFound == "")}");
        var nullValue = this.config["NullSample"];
        this.logger.LogDebug($"NullValue Null?:{(nullValue == null)} Empty:{(nullValue == "")}");

        return Json(new Book
        {
            Id = 1,
            Name = "Hello World"
        });
    }
...
Enter fullscreen mode Exit fullscreen mode

Result

dbug: ConfigSample.Controllers.HomeController[0]
      NotFound Null?:True Empty:False
2022-02-21 01:41:24.1251||DEBUG|ConfigSample.Controllers.HomeController|NotFound Null?:True Empty:False
2022-02-21 01:41:24.1459||DEBUG|ConfigSample.Controllers.HomeController|NullValue Null?:False Empty:True
dbug: ConfigSample.Controllers.HomeController[0]
      NullValue Null?:False Empty:True
Enter fullscreen mode Exit fullscreen mode

Get array values

I can't get array values like primitive types.

HomeController.cs

...
    [Route("")]
    public string Index()
    {
...
        // this return null
        this.logger.LogDebug(this.config["SampleArray"]);

        return Json(new Book
        {
            Id = 1,
            Name = "Hello World"
        });
    }
...
Enter fullscreen mode Exit fullscreen mode

Result

2022-02-21 02:01:14.6479||DEBUG|ConfigSample.Controllers.HomeController|[null]
dbug: ConfigSample.Controllers.HomeController[0]
      [null]
Enter fullscreen mode Exit fullscreen mode

To get the value, I have to use "GetSection".

HomeController.cs

...
    [Route("")]
    public string Index()
    {
...
        var aryList = this.config.GetSection("SampleArray");
        foreach(var ary in aryList.AsEnumerable())
        {        
            this.logger.LogDebug($"Array Key: {ary.Key} Value: {ary.Value}");
        }
        // I also can get value from the index.
        this.logger.LogDebug($"Object {aryList.GetValue(typeof(string), "0")}");

        return Json(new Book
        {
            Id = 1,
            Name = "Hello World"
        });
    }
...
Enter fullscreen mode Exit fullscreen mode

Result

dbug: ConfigSample.Controllers.HomeController[0]
      Array Key: SampleArray Value:
2022-02-21 02:14:59.8252||DEBUG|ConfigSample.Controllers.HomeController|Array Key: SampleArray Value:
dbug: ConfigSample.Controllers.HomeController[0]
      Array Key: SampleArray:1 Value: World
2022-02-21 02:14:59.8435||DEBUG|ConfigSample.Controllers.HomeController|Array Key: SampleArray:1 Value: World
2022-02-21 02:14:59.8435||DEBUG|ConfigSample.Controllers.HomeController|Array Key: SampleArray:0 Value: Hello
dbug: ConfigSample.Controllers.HomeController[0]
      Array Key: SampleArray:0 Value: Hello
dbug: ConfigSample.Controllers.HomeController[0]
      Object Hello
2022-02-21 02:14:59.8474||DEBUG|ConfigSample.Controllers.HomeController|Object Hello
Enter fullscreen mode Exit fullscreen mode

Or I can bind into variables.

HomeController.cs

...
    [Route("")]
    public string Index()
    {
...
        var stringList = new List<string>();
        this.config.GetSection("SampleArray").Bind(stringList);
        foreach(var ary in stringList)
        {        
            this.logger.LogDebug($"String Value: {ary}");
        }

        return Json(new Book
        {
            Id = 1,
            Name = "Hello World"
        });
    }
...
Enter fullscreen mode Exit fullscreen mode

Result

dbug: ConfigSample.Controllers.HomeController[0]
      String Value: Hello
2022-02-21 02:14:59.8474||DEBUG|ConfigSample.Controllers.HomeController|String Value: Hello
dbug: ConfigSample.Controllers.HomeController[0]
      String Value: World
2022-02-21 02:14:59.8474||DEBUG|ConfigSample.Controllers.HomeController|String Value: World
Enter fullscreen mode Exit fullscreen mode

Get object values

I also can get and bind object values.

HomeController.cs

...
    [Route("")]
    public string Index()
    {
...
        var sampleBook = this.config.GetSection("SampleBook").Get<Book>();
        this.logger.LogDebug($"SampleBook Value: {sampleBook}");

        var sampleBooks = new List<Book>();
        this.config.GetSection("SampleBooks").Bind(sampleBooks);
        foreach(var book in sampleBooks)
        {
            this.logger.LogDebug($"SampleBooks Value: {book}");
        }

        return Json(new Book
        {
            Id = 1,
            Name = "Hello World"
        });
    }
...
Enter fullscreen mode Exit fullscreen mode

Constructor

One important thing is I have to use empty constructor for binding classes.

When I created a class like below, I could get only null.

Book.cs(Before)

namespace ConfigSample.Books.Models;

public record Book
{
    public int Id { get; init; }
    public string Name { get; init; } = "";
    // DON'T DO THIS
    public Book(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
Enter fullscreen mode Exit fullscreen mode

After I remove the constructor, I can bind the values.

Book.cs(After)

namespace ConfigSample.Books.Models;

public record Book
{
    public int Id { get; init; }
    public string Name { get; init; } = "";
}
Enter fullscreen mode Exit fullscreen mode

Result

2022-02-21 02:33:55.8597||DEBUG|ConfigSample.Controllers.HomeController|SampleBook Value: Book { Id = 5, Name = Sample }

dbug: ConfigSample.Controllers.HomeController[0]
      SampleBook Value: Book { Id = 5, Name = Sample }
dbug: ConfigSample.Controllers.HomeController[0]
      SampleBooks Value: Book { Id = 6, Name = Sample1 }
2022-02-21 02:33:55.8768||DEBUG|ConfigSample.Controllers.HomeController|SampleBooks Value: Book { Id = 6, Name = Sample1 }
dbug: ConfigSample.Controllers.HomeController[0]
      SampleBooks Value: Book { Id = 7, Name = Sample2 }
2022-02-21 02:33:55.8768||DEBUG|ConfigSample.Controllers.HomeController|SampleBooks Value: Book { Id = 7, Name = Sample2 }
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
dr_dimaka profile image
Dmitry Pavlov • Edited on

To get array values from appSettings.json you could use typed settings class like this:

public class SampleBook
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class AppSettings
{
    public string SampleText { get; set; }
    public int SampleNumber { get; set; }
    public bool SampleBoolean { get; set; }
    public List<string> SampleArray { get; set; }
    public SampleBook SampleBook { get; set; }
    public List<SampleBook> SampleBooks { get; set; }
    public SampleBook NullSample { get; set; }
}
Enter fullscreen mode Exit fullscreen mode

... and initialize it using Microsoft.Extensions.DependencyInjection package via OptionsConfigurationServiceCollectionExtensions with this line of code

services.Configure<AppSettings>(configuration); 
Enter fullscreen mode Exit fullscreen mode

where configuration is IConfiguration and services - IServiceCollection

Hope that helps!
Digitally yours, the Coding-Machine.NET

Collapse
 
masanori_msl profile image
Masui Masanori Author

Thank you for your great comment!
I will try your suggestion on my next ASP NET Core project :)

๐ŸŒš Life is too short to browse without dark mode