包介绍 - Fluent Validation (用于验证)

1
Install-Package FluentValidation

 

如果你使用MVC5 可以使用下面的包

1
Install-Package FluentValidation.MVC5

 

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class CustomerValidator : AbstractValidator<Customer>
    {
        public CustomerValidator()
        {
            //不能为空
            RuleFor(customer => customer.Surname).NotEmpty();
             
            //自定义提示语
            RuleFor(customer => customer.Forename).NotEmpty().WithMessage("Pls specify a first name");
 
            //有条件的判断
            RuleFor(customer => customer.Discount).NotEqual(0).When(customer => customer.HasDiscount);
 
            //字符串长度的限制
            RuleFor(customer => customer.Address).Length(20, 250);
 
            //使用自定义验证器
            RuleFor(customer => customer.PostCode).Must(BeAValidPostCode).WithMessage("Pls specify a valid postCode");
 
        }
 
        /// <summary>
        /// 自定义验证
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        private bool BeAValidPostCode(string arg)
        {
            throw new NotImplementedException();
        }
    }
1
2
3
4
5
6
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
ValidationResult results = validator.Validate(customer);
 
bool validationSucceeded = results.IsValid;
IList<ValidationFailure> failures = results.Errors;

  

在一个属性上应用链式验证

1
2
3
4
5
public class CustomerValidator : AbstractValidator<Customer> {
  public CustomerValidator {
    RuleFor(customer => customer.Surname).NotNull().NotEqual("foo");
  }
}

 

抛出例外

1
2
3
4
Customer customer = new Customer();
CustomerValidator validator = new CustomerValidator();
 
validator.ValidateAndThrow(customer);

 

在复杂属性里面使用验证

1
2
3
4
5
6
7
8
9
10
11
12
public class Customer {
  public string Name { get; set; }
  public Address Address { get; set; }
}
 
public class Address {
  public string Line1 { get; set; }
  public string Line2 { get; set; }
  public string Town { get; set; }
  public string County { get; set; }
  public string Postcode { get; set; }
}

 

1
2
3
4
5
6
public class AddressValidator : AbstractValidator<Address> {
  public AddressValidator() {
    RuleFor(address => address.Postcode).NotNull();
    //etc
  }
}

 

1
2
3
4
5
6
public class CustomerValidator : AbstractValidator<Customer> {
  public CustomerValidator() {
    RuleFor(customer => customer.Name).NotNull();
    RuleFor(customer => customer.Address).SetValidator(new AddressValidator())
  }
}

 

在集合属性中使用Validator

1
2
3
4
5
6
public class OrderValidator : AbstractValidator<Order> {
    public OrderValidator() {
        RuleFor(x => x.ProductName).NotNull();
        RuleFor(x => x.Cost).GreaterThan(0);
    }
}

 

1
2
3
4
5
6
7
8
public class CustomerValidator : AbstractValidator<Customer> {
    public CustomerValidator() {
        RuleFor(x => x.Orders).SetCollectionValidator(new OrderValidator());
    }
}
 
var validator = new CustomerValidator();
var results = validator.Validate(customer);

集合验证的错误信息如下

1
2
3
4
5
foreach(var result in results.Errors) {
   Console.WriteLine("Property name: " + result.PropertyName);
   Console.WriteLine("Error: " + result.ErrorMessage);
   Console.WriteLine("");
}

 

1
2
3
4
5
Property name: Orders[0].Cost
Error: 'Cost' must be greater than '0'.
 
Property name: Orders[1].ProductName
Error: 'Product Name' must not be empty.

 

验证集合  

RuleSet能让你选择性的验证某些验证组 忽略某些验证组

1
2
3
4
5
6
7
8
9
10
public class PersonValidator : AbstractValidator<Person> {
  public PersonValidator() {
     RuleSet("Names", () => {
        RuleFor(x => x.Surname).NotNull();
        RuleFor(x => x.Forename).NotNull();
     });
  
     RuleFor(x => x.Id).NotEqual(0);
  }
}

下面的代码我们只验证Person的Surname和ForeName两个属性

1
2
3
var validator = new PersonValidator();
var person = new Person();
var result = validator.Validate(person, ruleSet: "Names");

 

一次验证多个集合

1
validator.Validate(person, ruleSet: "Names,MyRuleSet,SomeOtherRuleSet")

 

同样你可以验证那些没有被包含到RuleSet里面的规则  这些验证是一个特殊的ruleset 名为"default"

1
validator.Validate(person, ruleSet: "default,MyRuleSet")

 

正则表达式验证器

1
RuleFor(customer => customer.Surname).Matches("some regex here");

 

Email验证器

1
RuleFor(customer => customer.Email).EmailAddress();

 

覆盖默认的属性名

1
RuleFor(customer => customer.Surname).NotNull().WithName("Last name");

或者

1
2
3
4
public class Person {
  [Display(Name="Last name")]
  public string Surname { get; set; }
}

 

设置验证条件

1
2
3
4
When(customer => customer.IsPreferred, () => {
   RuleFor(customer => customer.CustomerDiscount).GreaterThan(0);
   RuleFor(customer => customer.CreditCardNumber).NotNull();
});

 

写一个自定义属性验证器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class ListMustContainFewerThanTenItemsValidator<T> : PropertyValidator {
 
    public ListMustContainFewerThanTenItemsValidator()
        : base("Property {PropertyName} contains more than 10 items!") {
         
    }
 
    protected override bool IsValid(PropertyValidatorContext context) {
        var list = context.PropertyValue as IList<T>;
 
        if(list != null && list.Count >= 10) {
            return false;
        }
 
        return true;
    }
}

 

1
2
3
4
5
public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
       RuleFor(person => person.Pets).SetValidator(new ListMustContainFewerThanTenItemsValidator<Pet>());
    }
}

 

 

与MVC集成

1. 

1
2
3
4
5
6
7
8
protected void Application_Start() {
    AreaRegistration.RegisterAllAreas();
 
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
 
    FluentValidationModelValidatorProvider.Configure();
}

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[Validator(typeof(PersonValidator))]
public class Person {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int Age { get; set; }
}
  
public class PersonValidator : AbstractValidator<Person> {
    public PersonValidator() {
        RuleFor(x => x.Id).NotNull();
        RuleFor(x => x.Name).Length(0, 10);
        RuleFor(x => x.Email).EmailAddress();
        RuleFor(x => x.Age).InclusiveBetween(18, 60);
    }
}

3.

1
2
3
4
5
6
7
8
9
10
11
[HttpPost]
    public ActionResult Create(Person person) {
  
        if(! ModelState.IsValid) { // re-render the view when validation failed.
            return View("Create", person);
        }
  
        TempData["notice"] = "Person successfully created";
        return RedirectToAction("Index");
  
    }

或者只验证指定的RuleSet

1
2
3
public ActionResult Save([CustomizeValidator(RuleSet="MyRuleset")] Customer cust) {
  // ...
}

或者只验证指定的属性

1
2
3
public ActionResult Save([CustomizeValidator(Properties="Surname,Forename")] Customer cust) {
  // ...
}

另外在验证的权限还有一个钩子 可以通过实现IValidatorInterceptor在验证的前后做一些工作

1
2
3
4
5
public interface IValidatorInterceptor {
    ValidationContext BeforeMvcValidation(ControllerContext controllerContext, ValidationContext validationContext);
  
    ValidationResult AfterMvcValidation(ControllerContext controllerContext, ValidationContext validationContext, ValidationResult result);
}

  

posted @   irocker  阅读(1989)  评论(0编辑  收藏  举报
编辑推荐:
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
阅读排行:
· 《HelloGitHub》第 108 期
· Windows桌面应用自动更新解决方案SharpUpdater5发布
· 我的家庭实验室服务器集群硬件清单
· Supergateway:MCP服务器的远程调试与集成工具
· C# 13 中的新增功能实操
点击右上角即可分享
微信分享提示