Reputation: 378
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; }
}
Upvotes: 3
Views: 975
Reputation: 9606
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);
}
}
Upvotes: 2