API传参
在操作方法的参数前面使用Attribute
幂等性
对请求的数据验证
简单验证
using System.ComponentModel.DataAnnotations;
public class TouristRouteForCreationDto
{
[Required(ErrorMessage ="title不能为空")]
[MaxLength(1500)]
public string Title { get; set; }
[Required]
[MaxLength(1500)]
public string Description { get; set; }
}
属性级别验证
//增加验证Title和Description不能相同
using System.ComponentModel.DataAnnotations;
public class TouristRouteForCreationDto:IValidatableObject
{
[Required(ErrorMessage ="title不能为空")]
[MaxLength(1500)]
public string Title { get; set; }
[Required]
[MaxLength(1500)]
public string Description { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Title == Description)
{
//yield return 保证ValidationResult后面的代码,下次调用还会继续执行
//TouristRouteForCreationDto代表错误路径
yield return new ValidationResult("名称和描述不能相同", new[] { "TouristRouteForCreationDto"});
}
}
}
类级别验证
//创建Attribute
public class TouristRouteTitleMustBeDifferentFromDescriptionAttribute : ValidationAttribute
{
protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
{
//获得实例
var touristRouteDto = (TouristRouteForCreationDto)validationContext.ObjectInstance;
if (touristRouteDto.Title == touristRouteDto.Description)
{
return new ValidationResult(
"路线名称必须与路线描述不同",
new[] { "TouristRouteForCreationDto" }
);
}
return ValidationResult.Success;
}
}
[TouristRouteTitleMustBeDifferentFromDescriptionAttribute]//应用属性
public class TouristRouteForCreationDto
{
[Required(ErrorMessage ="title不能为空")]
[MaxLength(1500)]
public string Title { get; set; }
[Required]
[MaxLength(1500)]
public string Description { get; set; }
}
验证失败返回422状态码
//在program中设置
builder.Services.AddControllers(opt => {
opt.ReturnHttpNotAcceptable = true;//可以接收其他格式如xml
}).AddXmlDataContractSerializerFormatters()
.ConfigureApiBehaviorOptions(setupAction => {
setupAction.InvalidModelStateResponseFactory = context =>
{
var problemDetail = new ValidationProblemDetails(context.ModelState)
{
Type = "无所谓",
Title = "数据验证失败",
Status = StatusCodes.Status422UnprocessableEntity,
Detail = "请看详细说明",
Instance = context.HttpContext.Request.Path //请求路径
};
problemDetail.Extensions.Add("traceId", context.HttpContext.TraceIdentifier);//追踪Id
return new UnprocessableEntityObjectResult(problemDetail)
{
ContentTypes = { "application/problem+json" }
};
};
});