简体   繁体   中英

Reading config item and using `IOptions<T>` failing

I don't get it! I'd swear I'm following the documentation ( Options pattern in ASP.NET Core ) to the letter, yet once I get into my service, the option value is null.

Here's the appsettings.json file contents;

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConfigStrings": {
    "IDProofingQuestionsPath": "C:\\dev\\...\\wwwroot\\sample-data\\idProofingQuestionsMOCK.json"
  }
}

(And just so you know, this path is for testing some stuff, it's not going to be permanent.)

Here's my ConfigureServices() method.

public void ConfigureServices(IServiceCollection services)
{
    // IDProofingQuestionsPathOptions.IDProofingQuestionsPath <- Section:Option string for the Settings file.
    services.Configure<IDProofingQuestionsPathOptions>(Configuration.GetSection(IDProofingQuestionsPathOptions.IDProofingQuestionsPath));

    // This is the service into which I'm trying to inject this 'Option'
    services.AddScoped<IIDProofingServices, IDProofingServices>();

    services.AddDistributedMemoryCache();

    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromSeconds(10);
        options.Cookie.HttpOnly = true;
        options.Cookie.IsEssential = true;
    });

    services.AddControllersWithViews();
}

And here's the code for my service, into which I'm trying to inject the IDProofingQuestionsPathOptions instance.

public class IDProofingServices : IIDProofingServices
{
    private readonly string _proofingQuestionsPath;

    /// <summary>
    /// This is a parameterized constructor for allowing Dependency Injection
    /// </summary>
    public IDProofingServices(
        IOptions<IDProofingQuestionsPathOptions> proofingQuestionsPath)
    {
        if (proofingQuestionsPath == null)
        {
            throw new ArgumentNullException(nameof(proofingQuestionsPath));
        }

        if (string.IsNullOrWhiteSpace(proofingQuestionsPath.Value.IdProofingQuestionsPath))
        {
            // my code ends up here, and I just do NOT get what I'm doing wrong.
            throw new ArgumentNullException("proofingQuestionsPath.Value.IdProofingQuestionsPath");
        }

        _proofingQuestionsPath = proofingQuestionsPath.Value.IdProofingQuestionsPath;
    }

    ...
    

Oh, and of course the option(s) object.

public class IDProofingQuestionsPathOptions
{
    public const string IDProofingQuestionsPath = "ConfigStrings:IDProofingQuestionsPath";

    public string IdProofingQuestionsPath { get; set; }
}

The Configure method expects a configuration section object , but your call to GetSection only offers a string value without any children which could be bound to the options object.

A straightforward fix would be binding directly to the ConfigStrings property, or introducing a JSON wrapper for your path property.


Small minimized example for the latter solution:

Startup :

public void ConfigureServices(IServiceCollection services)
{
    // Bind to the 'MyPathOptions' wrapper object
    services.Configure<PathOptions>(Configuration.GetSection("ConfigStrings:MyPathOptions"));

    // ...
}

PathOptions :

public class PathOptions
{
    public string MyPath { get; set; }
}

appsettings.json :

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*",
  "ConfigStrings": {
    "MyPathOptions": {
      "MyPath": "abc"
    }
  }
}

TestController :

[Route("")]
public class TestController : Controller
{
    private readonly IOptions<PathOptions> _pathOptions;

    public TestController(IOptions<PathOptions> pathOptions)
    {
        _pathOptions = pathOptions ?? throw new ArgumentNullException(nameof(pathOptions));
    }

    [HttpGet]
    public IActionResult Index()
    {
        return Ok(_pathOptions);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM