首页 > 解决方案 > 读取配置项并使用`IOptions` 失败

问题描述

我不明白!我发誓我会严格遵守文档(ASP.NET Core中的 Options 模式),但是一旦我开始使用我的服务,选项值为 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;
    }

    ...
    

哦,当然还有 option(s) 对象。

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

    public string IdProofingQuestionsPath { get; set; }
}

标签: c#asp.net-coreconfiguration

解决方案


Configure方法需要一个配置部分object,但您的调用GetSection仅提供一个字符串值,没有任何可以绑定到选项对象的子项。

一个简单的解决方法是直接绑定到该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);
    }
}

推荐阅读