Map appsettings.json to class
Asked Answered
U

4

13

I'm trying to convert appsettings.json to C# class

I use Microsoft.Extensions.Configuration to read the configuration from appsettings.json

I write the following code using reflection but I'm looking for a better solution

foreach (var (key, value) in configuration.AsEnumerable())
{
    var property = Settings.GetType().GetProperty(key);
    if (property == null) continue;
    
    object obj = value;
    if (property.PropertyType.FullName == typeof(int).FullName)
        obj = int.Parse(value);
    if (property.PropertyType.FullName == typeof(long).FullName)
        obj = long.Parse(value);
    property.SetValue(Settings, obj);
}
Ulrikaumeko answered 18/1, 2021 at 22:2 Comment(1)
Options pattern solves this elegantly. Check out the offical docs.Dudleyduds
C
21

Build configuration from appsettings.json file:

var config = new ConfigurationBuilder()
            .AddJsonFile("appsettings.json", optional = false)
            .Build()

Then add Microsoft.Extensions.Configuration.Binder nuget package. And you will have extensions to bind configuration (or configuration section) to the existing or new object.

E.g. you have a settings class (btw by convention it's called options)

public class Settings
{
    public string Foo { get; set; }
    public int Bar { get; set; }
}

And appsettings.json

{
  "Foo": "Bob",
  "Bar": 42
}

To bind configuration to new object you can use Get<T>() extension method:

var settings = config.Get<Settings>();

To bind to existing object you can use Bind(obj):

var settings = new Settings();
config.Bind(settings);
Costume answered 18/1, 2021 at 22:20 Comment(3)
there is no Get and Bind methodUlrikaumeko
@AliRezaBeigy then missed the part of adding Microsoft.Extensions.Configuration.Binder packageCostume
@AliRezaBeigy bit late, i had this, i didn't add the .Build() at the end of instantiating the config varAudwen
B
4

You can use Dictionary to get the json, and then use JsonSerializer to convert the json.

public IActionResult get()
    {
        Dictionary<string, object> settings = configuration
        .GetSection("Settings")
        .Get<Dictionary<string, object>>();
        string json = System.Text.Json.JsonSerializer.Serialize(settings);

        var setting = System.Text.Json.JsonSerializer.Deserialize<Settings>(json);

        return Ok();
    }

Here is the model

public class Settings
{
    public string property1 { get; set; }
    public string property2 { get; set; }
}

In appsettings.json

 "Settings": {
  "property1": "ap1",
  "property2": "ap2"
 },

enter image description here

Bunyan answered 19/1, 2021 at 10:7 Comment(0)
E
2

I'm shocked nobody has suggested using the IOptions pattern or even asked if this a system involving DI (Dependency Injection). If the system is indeed using DI, I would suggest using the IOptions pattern described here Options Pattern as it not only allows for the options to be injected where they're needed, but also allows for change notifications so you can receive configuration changes and act on them.

Einstein answered 2/8, 2023 at 9:55 Comment(0)
C
0

Don't reinvent the wheel! As some users have mentioned, try using the Options pattern which is provided by Microsoft.

Here is a simple example of how to do it:

appsetting.json

{
  "AppSettings": {
    "Setting1": "Value1",
    "Setting2": "Value2"
  }
}

AppOptions.cs

public class AppOptions
{
    public string Setting1 { get; set; }
    public string Setting2 { get; set; }
}

Configure it with dependency injection

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

This is the way you inject it into service, I use IOptions, and I highly suggest checking other Options interfaces such as IOptionsSnapshot based on your case.

public SomeService(IOptions<AppOptions> appOptions)
{
    _appOptions = appOptions.Value;
}
Cessionary answered 28/7, 2024 at 9:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.