当前位置 主页 > 服务器问题 > Linux/apache问题 >

    .Net Core3.0 WEB API中使用FluentValidation验证(批量注入)

    栏目:Linux/apache问题 时间:2019-12-06 22:07

    为什么要使用FluentValidation

    1.在日常的开发中,需要验证参数的合理性,不紧前端需要验证传毒的参数,后端也需要验证参数
    2.在领域模型中也应该验证,做好防御性的编程是一种好的习惯(其实以前重来不写的,被大佬教育了一番)
    3.FluentValidation 是.NET 开发的验证框架,开源,主要是简单好用,内置了一些常用的验证器,可以直接使用,扩展也很方便

    使用FluentValidation

    1.引入FluentValidation.AspNetCore NuGet包
    2.建立需要验证的类

    /// <summary>
    /// 创建客户
    /// </summary>
    public class CreateCustomerDto
    {
      /// <summary>
      /// 客户姓名
      /// </summary>
      public string CustomerName { get; set; }
      /// <summary>
      /// 客户年龄
      /// </summary>
      public string CustomerAge { get; set; }
      /// <summary>
      /// 客户电话
      /// </summary>
      public string CustomerPhone { get; set; }
      /// <summary>
      /// 客户地址
      /// </summary>
      public Address CustomerAddress { get; set; }
    }
    
    /// <summary>
    /// 验证
    /// </summary>
    public class CreateCustomerDtoValidator : AbstractValidator<CreateCustomerDto>
    {
      public CreateCustomerDtoValidator()
      {
        RuleFor(x => x.CustomerName)
           .NotEmpty()
           .WithMessage("客户姓名不能为空");
        RuleFor(x => x.CustomerPhone)
           .NotEmpty()
           .WithMessage("客户电话不能为空");
    
      }
    }
    
    

    3.统一返回验证的信息,ResponseResult为全局统一参数返回的类

      /// <summary>
      /// 添加AddFluentValidationErrorMessage
      /// </summary>
      /// <returns></returns>
      public DependencyInjectionService AddFluentValidationErrorMessage()
      {
        _services.Configure<ApiBehaviorOptions>(options =>
        {
          options.InvalidModelStateResponseFactory = (context) =>
          {
            var errors = context.ModelState
              .Values
              .SelectMany(x => x.Errors
                    .Select(p => p.ErrorMessage))
              .ToList();
            var result = new ResponseResult<List<string>>
            {
              StatusCode = "00009",
              Result = errors,
              Message = string.Join(",", errors.Select(e => string.Format("{0}", e)).ToList()),
              IsSucceed = false
            };
    
            return new BadRequestObjectResult(result);
          };
        });
        return _dependencyInjectionConfiguration;
      }
    
    

    4.注入验证的类

    使用builder.RegisterType().As<IValidator>();比较麻烦每次新增都需要添加一次注入
    所以我们使用批量的注入,来减少麻烦,通过反射获取所有的验证的类批量注入

      /// <summary>
      /// 添加MVC
      /// </summary>
      /// <returns></returns>
      public DependencyInjectionService AddMvc()
      {
        _services.AddControllers(options => 
        { 
          options.Filters.Add(typeof(LogHelper));
        }).AddJsonOptions(options =>
        {
          //忽略循环引用
          //options.JsonSerializerOptions.IgnoreReadOnlyProperties = true;
        }).AddFluentValidation(options =>
        {
          options.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
          var validatorList = GetFluentValidationValidator("ConferenceWebApi");
          foreach (var item in validatorList)
          {
            options.RegisterValidatorsFromAssemblyContaining(item);
          }
        });
        return _dependencyInjectionConfiguration;
      }
    
      /// <summary>
      /// 获取所有的FluentValidation Validator的类
      /// </summary>
      public IEnumerable<Type> GetFluentValidationValidator(string assemblyName)
      {
        if (assemblyName == null)
          throw new ArgumentNullException(nameof(assemblyName));
        if (string.IsNullOrEmpty(assemblyName))
          throw new ArgumentNullException(nameof(assemblyName));
    
        var implementAssembly = RuntimeHelper.GetAssembly(assemblyName);
        if (implementAssembly == null)
        {
          throw new DllNotFoundException($"the dll ConferenceWebApi not be found");
        }
        var validatorList = implementAssembly.GetTypes().Where(e => e.Name.EndsWith("Validator"));
        return validatorList;
      }