Verify of batch injection using FluentValidation in Net Core 3.0 WEB API

  • 2021-11-13 01:17:04
  • OfStack

Why use FluentValidation

1. In daily development, it is necessary to verify the rationality of parameters. If it is not tight, the front-end needs to verify the parameters of virus transmission, and the back-end also needs to verify the parameters
2. It should also be verified in the domain model that it is a good habit to do defensive programming well (in fact, I didn't write it again before, and I was educated by the big brothers once)
3. FluentValidation is the verification framework developed by NET, open source, mainly simple and easy to use, built-in 1 common validator, can be used directly, expansion is also very convenient

Using FluentValidation

1. Introducing the FluentValidation. AspNetCore NuGet package
2. Create classes to validate


/// <summary>
///  Create a customer 
/// </summary>
public class CreateCustomerDto
{
  /// <summary>
  ///  Customer name 
  /// </summary>
  public string CustomerName { get; set; }
  /// <summary>
  ///  Customer age 
  /// </summary>
  public string CustomerAge { get; set; }
  /// <summary>
  ///  Customer telephone number 
  /// </summary>
  public string CustomerPhone { get; set; }
  /// <summary>
  ///  Customer address 
  /// </summary>
  public Address CustomerAddress { get; set; }
}

/// <summary>
///  Validation 
/// </summary>
public class CreateCustomerDtoValidator : AbstractValidator<CreateCustomerDto>
{
  public CreateCustomerDtoValidator()
  {
    RuleFor(x => x.CustomerName)
       .NotEmpty()
       .WithMessage(" Customer name cannot be blank ");
    RuleFor(x => x.CustomerPhone)
       .NotEmpty()
       .WithMessage(" Customer phone cannot be empty ");

  }
}

3. System 1 returns validation information, and ResponseResult is the class returned by the global system 1 parameter


  /// <summary>
  ///  Add 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. Inject validated classes

Use builder. RegisterType (). As < IValidator > (); It's troublesome to add injection once every time you add it
So we use batch injection to reduce the trouble and get all the verified class batch injection through reflection


  /// <summary>
  ///  Add MVC
  /// </summary>
  /// <returns></returns>
  public DependencyInjectionService AddMvc()
  {
    _services.AddControllers(options => 
    { 
      options.Filters.Add(typeof(LogHelper));
    }).AddJsonOptions(options =>
    {
      // Ignore circular references 
      //options.JsonSerializerOptions.IgnoreReadOnlyProperties = true;
    }).AddFluentValidation(options =>
    {
      options.RunDefaultMvcValidationAfterFluentValidationExecutes = false;
      var validatorList = GetFluentValidationValidator("ConferenceWebApi");
      foreach (var item in validatorList)
      {
        options.RegisterValidatorsFromAssemblyContaining(item);
      }
    });
    return _dependencyInjectionConfiguration;
  }

  /// <summary>
  ///  Gets all of the FluentValidation Validator Class of 
  /// </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;
  }

5. It's 10 points easy to use


  /// <summary>
  ///  Create a customer 
  /// </summary>
  /// <param name="input"></param>
  /// <returns></returns>
  [HttpPost]
  public async Task<ResponseResult<string>> CreateCustomer([FromBody] CreateCustomerDto input)
  {
    var createCustomerCommand = new CreateCustomerCommand(input.CustomerName,input.CustomerAge,input.CustomerPhone,input.CustomerAddress);
    await _commandService.SendCommandAsync(createCustomerCommand);
    var result = new ResponseResult<string>
    {
      IsSucceed = true,
      Result = " Create customer success! "
    };
    return result;
  }


Related articles: