首页 > 技术文章 > 17 | 为选项数据添加验证:避免错误配置的应用接收用户流量

wwwk 2022-02-08 23:58 原文

三种验证方法

  • 直接注册验证函数
  • 实现IValidateOptions
  • 使用Microsoft.Extensions.Options.DataAnnotations

示例


直接注册验证函数
继续使用上一节代码,需要稍微修改一点代码。

using Microsoft.Extensions.Configuration;
using OptionsDemo.Services;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class OrderServiceExtensions
    {
        public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration)
        {
            // 需要添加验证的时候,这里就不能用Configure,而是AddOptions方法
            //services.Configure<OrderServiceOptions>(configuration);

            services.AddOptions<OrderServiceOptions>()
                // 使用configuration绑定
                .Configure(options => configuration.Bind(options))
                // 添加验证和提示
                .Validate(options => options.MaxOrderCount <= 10086, "MaxOrderCount不能超过10086");

            services.AddSingleton<IOrderService, OrderService>();
            return services;
        }
    }
}

需要添加验证的时候,这里就不能用Configure,而是AddOptions方法。
利用configuration.Bind将配置绑定到OrderServiceOptions上,使用Validate添加验证和失败提示
将配置文件MaxOrderCount值修改为10087之后,执行代码:
image.png
image.png
引发异常,显示失败提示。


属性注入
这里我们切换为属性注入的方式

using Microsoft.Extensions.Configuration;
using OptionsDemo.Services;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class OrderServiceExtensions
    {
        public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration)
        {
            // 需要添加验证的时候,这里就不能用Configure,而是AddOptions方法
            //services.Configure<OrderServiceOptions>(configuration);

            services.AddOptions<OrderServiceOptions>()
                // 使用configuration绑定
                .Configure(options => configuration.Bind(options))
                // 属性注入
                .ValidateDataAnnotations();

            services.AddSingleton<IOrderService, OrderService>();
            return services;
        }
    }
}

使用ValidateDataAnnotations(),并且给我们的配置类OrderServiceOptions属性MaxOrderCount定义验证属性
这里使用Range的验证属性,定义最小值1最大值10086,我们配置文件的值10087

public class OrderServiceOptions
{
    [Range(1,10086)]
    public int MaxOrderCount { get; set; } = 200;
}

执行程序:image.png


实现接口方式
我们首先定义验证类,验证类是需要实现IValidateOptions这个接口

public class OrderServiceValidateOptions : IValidateOptions<OrderServiceOptions>
{
	public ValidateOptionsResult Validate(string name, OrderServiceOptions options)
    {
    	if (options.MaxOrderCount > 10086)
         {
			return ValidateOptionsResult.Fail("MaxOrderCount不能大于10086");
         }
         return ValidateOptionsResult.Success;
	}
}
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Options;
using OptionsDemo.Services;

namespace Microsoft.Extensions.DependencyInjection
{
    public static class OrderServiceExtensions
    {
        public static IServiceCollection AddOrderService(this IServiceCollection services,IConfiguration configuration)
        {
            // 需要添加验证的时候,这里就不能用Configure,而是AddOptions方法
            //services.Configure<OrderServiceOptions>(configuration);

            services.AddOptions<OrderServiceOptions>()
                // 使用configuration绑定
                .Configure(options => configuration.Bind(options))
                // 接口
                .Services.AddSingleton<IValidateOptions<OrderServiceOptions>, OrderServiceValidateOptions>();

            services.AddSingleton<IOrderService, OrderService>();
            return services;
        }
    }
}

这里是使用服务注册进去的
执行代码:image.png

推荐阅读