如何在ASP.NET Core 2.2中使用IValidateOptions验证配置设置 [英] How to validate configuration settings using IValidateOptions in asp.net core 2.2

查看:199
本文介绍了如何在ASP.NET Core 2.2中使用IValidateOptions验证配置设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Microsoft的asp.net核心文档

Microsoft's asp.net core documentation briefly mentions that you can implement IValidateOptions<TOptions> to validate configuration settings from appsettings.json, but a complete example is not provided. How is IValidateOptions intended to be used? More specifically:

  • 您在哪里连接验证器类?
  • 如果验证,您如何记录一条有用的消息来解释问题所在 失败了吗?
  • Where do you wire up your validator class?
  • How can you log a useful message explaining what the problem is if validation fails?

[我实际上已经找到了解决方案.我正在发布我的代码,因为目前在stackoverflow上找不到任何提及IValidateOptions的内容.如果有人有更优雅的方法,我将有兴趣看到它.]

[I have actually found a solution already. I'm posting my code since I can't find any mention of IValidateOptions on stackoverflow at this time. If anyone has a more elegant approach I'd be interested in seeing it.]

推荐答案

我最终在

I eventually found an example of how this is done in the commit where the options validation feature was added. As with so many things in asp.net core, the answer is to add your validator to the DI container and it will automatically be used.

通过这种方法,PolygonConfiguration在验证后进入DI容器,并可以注入到需要它的控制器中.我更喜欢将IOptions<PolygonConfiguration>注入到我的控制器中.

With this approach the PolygonConfiguration goes into the DI container after validation and can be injected into the controllers that need it. I prefer this to injecting IOptions<PolygonConfiguration> into my controllers.

似乎第一次在容器中请求PolygonConfiguration实例时(即在实例化控制器时)运行验证代码.在启动过程中更早地进行验证可能会很好,但是我对此感到满意.

It appears that the validation code runs the first time an instance of PolygonConfiguration is requested from the container (i.e. when the controller is instantiated). It might be nice to validate earlier during startup, but I'm satisfied with this for now.

这就是我最终要做的:

public class Startup
{
    public Startup(IConfiguration configuration, ILoggerFactory loggerFactory)
    {
        Configuration = configuration;
        Logger = loggerFactory.CreateLogger<Startup>();
    }

    public IConfiguration Configuration { get; }
    private ILogger<Startup> Logger { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

        //Bind configuration settings
        services.Configure<PolygonConfiguration>(Configuration.GetSection(nameof(PolygonConfiguration)));

        //Add validator
        services.AddSingleton<IValidateOptions<PolygonConfiguration>, PolygonConfigurationValidator>();

        //Validate configuration and add to DI container
        services.AddSingleton<PolygonConfiguration>(container =>
        {
            try
            {
                return container.GetService<IOptions<PolygonConfiguration>>().Value;
            }
            catch (OptionsValidationException ex)
            {
                foreach (var validationFailure in ex.Failures)
                    Logger.LogError($"appSettings section '{nameof(PolygonConfiguration)}' failed validation. Reason: {validationFailure}");

                throw;
            }
        });
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
       ...
    }
}

appSettings.json,其中包含一些有效值和无效值

appSettings.json with some valid and invalid values

{
  "PolygonConfiguration": {
    "SupportedPolygons": [
      {
        "Description": "Triangle",
        "NumberOfSides": 3
      },
      {
        "Description": "Invalid",
        "NumberOfSides": -1
      },
      {
        "Description": "",
        "NumberOfSides": 6
      }
    ]
  }
}

验证器类本身

    public class PolygonConfigurationValidator : IValidateOptions<PolygonConfiguration>
    {
        public ValidateOptionsResult Validate(string name, PolygonConfiguration options)
        {
            if (options is null)
                return ValidateOptionsResult.Fail("Configuration object is null.");

            if (options.SupportedPolygons is null || options.SupportedPolygons.Count == 0)
                return ValidateOptionsResult.Fail($"{nameof(PolygonConfiguration.SupportedPolygons)} collection must contain at least one element.");

            foreach (var polygon in options.SupportedPolygons)
            {
                if (string.IsNullOrWhiteSpace(polygon.Description))
                    return ValidateOptionsResult.Fail($"Property '{nameof(Polygon.Description)}' cannot be blank.");

                if (polygon.NumberOfSides < 3)
                    return ValidateOptionsResult.Fail($"Property '{nameof(Polygon.NumberOfSides)}' must be at least 3.");
            }

            return ValidateOptionsResult.Success;
        }
    }

以及配置模型

    public class Polygon
    {
        public string Description { get; set; }
        public int NumberOfSides { get; set; }
    }

    public class PolygonConfiguration
    {
        public List<Polygon> SupportedPolygons { get; set; }
    }

这篇关于如何在ASP.NET Core 2.2中使用IValidateOptions验证配置设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆