验证要做三件事
- 定义验证规则
- 按验证规则进行检查
- 报告验证的错误。
在把错误报告给API消费者的时候,报告里并不包含到底是服务端还是API消费者引起的错误,这是状态码的工作。而通常响应的Body里面会包含一组验证错误信息,API消费者可以把这些信息展示给API消费者的用户。
定义验证规则
想要定义验证规则,我们可以使用ASP.NET Core内置的方式或者使用第三方库。
在ASP.NET Core里面,验证规则可以通过以下的方式来进行定义:
- Data Annotations
- 自定义Atrribute
- 实现IValidatableObject接口
ASP.NET Core 内置了一个 ModelState对象,它用来做验证规则检查,如果规则验证不通过的话,ModelState.IsValid()方法就会返回false
一、Data Annotation
public class TripManager
{
[Key]
public int Id { get; set; }
[ForeignKey( "HotelID" )]
public Hotel Hotel { get; set; }
public int HotelID { get; set; }
[ForeignKey( "CarID" )]
public Car Car { get; set; }
public int CarID { get; set; }
[DataType( DataType.Date )]
public DateTime CheckInDate { get; set; }
[DataType( DataType.Date )]
public DateTime CheckOutDate { get; set; }
[Column( "TodaysPrice" )]
[Range( 10.30, 46.60 )]
public double Price { get; set; }
public Person Responsable { get; set; }
}
public class Hotel
{
public int Id { get; set; }
[DisplayFormat( NullDisplayText = "无名称" )]
public string Name { get; set; }
}
public class Person
{
public int Id { get; set; }
[Display(Name = "姓名")]
[StringLength( 50,MininumLength = 10, ErrorMessage = "{0}的长度为{1}-{2}" )]
public string Name { get; set; }
[NotMapped]
public List<Place> VisitedPlaces { get; set; }
}
public class Car
{
public int Id { get; set; }
[Required(ErrorMessage = "{0}字段为必填")]
[MaxLength(100, ErrorMessage = "{0}的最大长度不能超过{1}"]
public string Model { get; set; }
public string Brand { get; set; }
}
ASP.NET Core 2.x 以前的验证写法
if(!ModelState.IsValid)
{
return UnprocessableEntity(ModeState);
}
ASP.NET Core 3.0 使用[ApiController]
注解时就可以省略 2.x 这样的判断,有错则自动返回400错误
二、自定义Atrribute
public class TestAttribute:ValidationAttribute
{
protected override ValidationResult IsValid(object value,ValidationContext validationContext)
{
var dto=(Hotel)validationContext.objectInstance; //获取对象
if(Name == "傻蛋")
{
return new ValidationResult("不能叫这么Low的名字",new[]{ nameof(Hotel)});
}
return ValidationResult.Success;
}
}
[Test]
public class Hotel
{
public int Id { get; set; }
public string Name { get; set; }
}
说明
- 当
[Test]
作用于属性时,value
指要验证的属性,validationContext
指的是对象 - 当
[Test]
作用于类时,value
和validationContext
相同,都指的是对象
三、实现IValidatableObject接口
public class Hotel:IValidatableObject
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(Name == "傻蛋")
{
yield return new ValidationResult("不能叫这么Low的名字",new[]{ nameof(Name)});
}
}
}
说明
先进行[ ]
属性标签的验证,再时行Validate
方法验证,Validate
方法是“类”级别的。