簡體   English   中英

使用選項模式時如何檢查缺少的配置部分?

[英]How can I check for a missing configuration section when using the Options pattern?

我有一個簡單的控制器,它使用選項模式從appsettings.json讀取一些配置。 只要appsettings.json配置正確,它就可以正常工作。 但是,如果appsettings.json中缺少我的配置部分怎么辦? 我希望得到一個Exceptionnull ,但我得到了一個具有默認值的MySettings對象(即MyPropertynull )。

我的控制器.cs

public class MyController : Controller
{
    private readonly string value;

    public MyController(IOptions<MySettings> options)
    {
        // Can I validate the `options` object here?
        this.value = options.Value.MyProperty;
    }

    [HttpGet("api/data")]
    public ActionResult<string> GetValue()
    {
        return this.Ok(this.value);
    }
}

我的設置.cs

public class MySettings
{
    public string MyProperty { get; set; }
}

Startup.cs(只顯示相關代碼)

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        // Tried this:
        services.Configure<MySettings>(Configuration.GetSection("MySettings"));

        // Tried this too:
        services.Configure<MySettings>(options => Configuration.GetSection("MySettings").Bind(options));
    }
}

應用設置.json

{
  "MySettings": {
    "MyProperty": "hello world"
  }
}

您可以通過以下方式強制執行它:

  1. 向模型添加數據注釋
public class MySettings
{
    [Required]
    public string MyProperty { get; set; }
}
  1. Bind調用后調用ValidateDataAnnotations
services
   .Configure<MySettings>(options => Configuration
     .GetSection("MySettings")
     .Bind(options))
     .ValidateDataAnnotations();
  1. 將屬性訪問包裝在一個 try catch 中,除了OptionsValidationException
try
{
   this.value = options.Value.MyProperty;
}
catch(OptionsValidationException ex)
{
   //handle the validation exception
}

我在這個 SO answer上找到了一種可能的解決方案。

添加一個擴展方法來驗證:

public static class ConfigurationExtensions
{
    public static T GetValid<T>(this IConfiguration configuration)
    {
        var config = configuration.Get<T>();

        try
        {
            Validator.ValidateObject(config, new ValidationContext(config), true);
        }
        catch(Exception e)
        {
            throw new NotSupportedException("Invalid Configuration", e);
        }

        return config;
    }
}

使用該擴展方法在 Startup.cs 中驗證和注冊實例:

var settings = Configuration.GetSection("MySettings").GetValid<MySettings>();
services.AddSingleton(settings);

更改控制器構造函數以直接接受MySettings對象(而不是IOptions<MySettings> ):

public MyController(MySettings options)
{
    this.value = options.MyProperty;
}

這種方法的另一個很好的結果是它消除了我們對IOptions的依賴,這稍微簡化了控制器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM