在对数据进行输入操作时候,后台有必要做数据校验,并给前端返回正确的提示和状态码。
文章列表:
- 属性级别数据校验
- 类级别数据校验
- 返回正确的状态码
属性级别数据校验
//用于数据写入的Dto IValidatableObject做数据校验的接口
public class TouristRouteForCreationDto : IValidatableObject
{
public string Title { get; set; }
public string Description { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Title == Description)
{
//yield return 保存当前函数的状态,下次调用时继续从当前位置处理。
yield return new ValidationResult(
"路线名称必须和路线描述不同",
new[] { "TouristRouteForCreationDto" }
);
}
}
}
我们可以直接通过实现IValidatableObject
接口的Validate
方法,来对相应的属性做复杂的验证操作。
上面代码验证规则表示当Title == Description
的时候,会给前端返回相应的错误信息。
类级别数据校验
1.在解决方案中可以创建一个ValidationAttributes
文件夹。
2.在该文件夹下面可以创建一个名为TourisRouteTitleMustBeDiffentFromDescriptionAttribute
的类
3.让该类继承ValidationAttribute
4.实现IsValid
方法
5.使用自定义的类。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
using Fakexiecheng.API.Dtos;
namespace Fakexiecheng.API.ValidationAttributes
{
public class TourisRouteTitleMustBeDiffentFromDescriptionAttribute:ValidationAttribute
{
protected override ValidationResult IsValid(
object value,
ValidationContext validationContext
)
{
//通过上下文关系 获得当前的对象
var touriRouteDto = (TouristRouteForManipulationDto)validationContext.ObjectInstance;
if (touriRouteDto.Title == touriRouteDto.Description)
{
//yield return 保存当前函数的状态,下次调用时继续从当前位置处理。具体看云盘.net 有实验验证
return new ValidationResult(
"路线名称必须和路线描述不同",
new[] { "TouristRouteForCreationDto" }
);
}
return ValidationResult.Success;
}
}
}
其中validationContext.ObjectInstance
为你要验证的类对象,需要做强制转换。
使用:
返回正确的状态码
一般数据验证错误都会给前端返回422的状态码,所以我们可以通过全局注册的方式注入。
在Startup
的ConfigureServices
方法中添加以下代码。
services.ConfigureApiBehaviorOptions(setupAction => {
//InvalidModelStateResponseFactory无效模型状态转移工厂
setupAction.InvalidModelStateResponseFactory = context => {
var problemDetail = new ValidationProblemDetails(context.ModelState)
{
Type = "无所谓",
Title = "数据验证失败",
Status = StatusCodes.Status422UnprocessableEntity,
Detail = "请看详细说明",
Instance = context.HttpContext.Request.Path //请求路径
};
//加上追踪ID
problemDetail.Extensions.Add("traeId", context.HttpContext.TraceIdentifier);
return new UnprocessableEntityObjectResult(problemDetail)
{
//问题类型 用于返回前端
ContentTypes = { "application/problem+json" }
};
};
});//ConfigureApiBehaviorOptions 验证数据是否非法的一个过程