读取配置项并使用 `IOptions<T>` 失败
Reading config item and using `IOptions<T>` failing
我不明白!我发誓我会严格按照文档 (Options pattern in ASP.NET Core) 进行操作,但是一旦我开始使用我的服务,选项值为 null。
这是 appsettings.json
文件内容;
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConfigStrings": {
"IDProofingQuestionsPath": "C:\dev\...\wwwroot\sample-data\idProofingQuestionsMOCK.json"
}
}
(如你所知,此路径用于测试某些内容,不会永久存在。)
这是我的 ConfigureServices()
方法。
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();
}
这是我的服务代码,我试图将 IDProofingQuestionsPathOptions
实例注入其中。
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;
}
...
哦,当然还有选项对象。
public class IDProofingQuestionsPathOptions
{
public const string IDProofingQuestionsPath = "ConfigStrings:IDProofingQuestionsPath";
public string IdProofingQuestionsPath { get; set; }
}
Configure
method expects a configuration section object, but your call to GetSection
仅提供 string 值,没有任何可以绑定到选项对象的子项。
一个简单的修复方法是直接绑定到 ConfigStrings
属性,或者为您的路径 属性.
引入一个 JSON 包装器
后一种解决方案的最小化示例:
启动:
public void ConfigureServices(IServiceCollection services)
{
// Bind to the 'MyPathOptions' wrapper object
services.Configure<PathOptions>(Configuration.GetSection("ConfigStrings:MyPathOptions"));
// ...
}
路径选项:
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"
}
}
}
测试控制器:
[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);
}
}
我不明白!我发誓我会严格按照文档 (Options pattern in ASP.NET Core) 进行操作,但是一旦我开始使用我的服务,选项值为 null。
这是 appsettings.json
文件内容;
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConfigStrings": {
"IDProofingQuestionsPath": "C:\dev\...\wwwroot\sample-data\idProofingQuestionsMOCK.json"
}
}
(如你所知,此路径用于测试某些内容,不会永久存在。)
这是我的 ConfigureServices()
方法。
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();
}
这是我的服务代码,我试图将 IDProofingQuestionsPathOptions
实例注入其中。
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;
}
...
哦,当然还有选项对象。
public class IDProofingQuestionsPathOptions
{
public const string IDProofingQuestionsPath = "ConfigStrings:IDProofingQuestionsPath";
public string IdProofingQuestionsPath { get; set; }
}
Configure
method expects a configuration section object, but your call to GetSection
仅提供 string 值,没有任何可以绑定到选项对象的子项。
一个简单的修复方法是直接绑定到 ConfigStrings
属性,或者为您的路径 属性.
后一种解决方案的最小化示例:
启动:
public void ConfigureServices(IServiceCollection services)
{
// Bind to the 'MyPathOptions' wrapper object
services.Configure<PathOptions>(Configuration.GetSection("ConfigStrings:MyPathOptions"));
// ...
}
路径选项:
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"
}
}
}
测试控制器:
[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);
}
}