Rahul
Rahul

Reputation: 1163

Unable to read/bind configuration settings with strongly-typed class using Named Options in Asp.Net Core 3

I am unable to bind configuration settings inside my appsettings.json to a strongly-types class using named options.

appsettings.json

"CJSettings": {
    "Normal": {
      "CSSUrl": "https://css.mydomain.com/main.min.css",
      "LogoName": "mysite-logo.png"
    },
    "WL": {
      "CSSUrl": "https://css.mydomain.com/main_wl.min.css",
      "LogoName": "mysite-WL-logo.png"
    },
    "SEG": {
      "CSSUrl": "https://css.mydomain.com/main_seg.min.css",
      "LogoName": "mysite-seg-logo.png"
    }}

CJSettings.cs

public class CJSettings
{
    public string CSSUrl { get; set; }
    public string LogoName { get; set; }
}

Startup.cs

services.Configure<CJSettings>("Normal", configuration.GetSection("CJSettings.Normal"));
services.Configure<CJSettings>("WL", configuration.GetSection("CJSettings.WL"));
services.Configure<CJSettings>("SEG", configuration.GetSection("CJSettings.SEG"));

NormalService.cs

My service where i am trying to read configuration data using name. but no success.

public class NormalService : INormalService
{
    private readonly CJSettings cjSettings;

    public NormalService(IOptionsMonitor<CJSettings> options)
    {
        this.cjSettings = options.Get("Normal");    //getting null values for both properties
    }
}

As you can see above, i tried reading data using name "Normal" but i am getting null values for both properties of CJSettings object.

named-options-read-null

please help me to fix this... Thanks

Upvotes: 0

Views: 810

Answers (1)

Dmitry Stepanov
Dmitry Stepanov

Reputation: 2914

I don't know why your code is not working. I can suggest the following solution that I'm always using:

public class CJSettings
{
    public UrlSettings Normal { get; set; }
    public UrlSettings WL { get; set; }
    public UrlSettings SEG { get; set; }
}

public class UrlSettings
{
    public string CSSUrl { get; set; }
    public string LogoName { get; set; }
}

Register options and services:

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CJSettings>(Configuration.GetSection(nameof(CJSettings)));
        services.AddTransient<INormalService, NormalService>();

        // the rest of your code
    }

Then inject options into a constructor of your service:

public class NormalService : INormalService
{
    private readonly CJSettings cjSettings;

    public NormalService(IOptions<CJSettings> options)
    {
        this.cjSettings = options.Value ?? throw new ArgumentNullException(nameof(CJSettings));
    }
}

This should work. I checked it out.

UPDATED

Actually your code is OK. You just need to use colons instead of dots in a key parameter of GetSection method:

services.Configure<CJSettings>("Normal", Configuration.GetSection("CJSettings:Normal"));
services.Configure<CJSettings>("WL", Configuration.GetSection("CJSettings:WL"));
services.Configure<CJSettings>("SEG", Configuration.GetSection("CJSettings:SEG"));

Upvotes: 2

Related Questions