Asp.net 一致输入模型验证错误报告
假设我有以下输入模型:Asp.net 一致输入模型验证错误报告,asp.net,.net,asp.net-core,asp.net-core-webapi,asp.net-core-3.1,Asp.net,.net,Asp.net Core,Asp.net Core Webapi,Asp.net Core 3.1,假设我有以下输入模型: public class InputModel { [Required] public string? Name { get; set; } [Required] public DateTime? Birthday { get; set; } } 如果未提供生日字段,则我会得到以下适当的响应: { "type": "https://tools.ietf.org/html/rfc7231#sectio
public class InputModel
{
[Required]
public string? Name { get; set; }
[Required]
public DateTime? Birthday { get; set; }
}
如果未提供生日字段,则我会得到以下适当的响应:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-818caf3d757ae345a735fd0f4a523ecb-e9f90641c111814c-00",
"errors": {
"Birthday": [
"The Birthday field is required."
]
}
}
但如果我提供的日期字符串无效,则返回以下内容:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-715471c843155940a6f0cae580cd1b69-247e6dbfe3442446-00",
"errors": {
"model": [
"The model field is required."
],
"$.birthday": [
"The JSON value could not be converted to System.Nullable`1[System.DateTime]. Path: $.birthday | LineNumber: 13 | BytePositionInLine: 37."
]
}
}
这两个响应模型不一致,这使得客户很难对验证错误进行推理
如何在转换器处理DateTime字符串之前对其进行验证,以便返回与第一个类似的响应模型?大概是这样的:
{
"type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"traceId": "00-818caf3d757ae345a735fd0f4a523ecb-e9f90641c111814c-00",
"errors": {
"Birthday": [
"The Birthday field is badly formed."
]
}
}
尝试定义datetime字段的数据类型,如下所示:
[Required]
[DataType(DataType.DateTime)]
public DateTime? Birthday { get; set; }
如何在DateTime字符串被
转换器,以便返回与第一个类似的响应模型
您可以创建一个自定义BadRequest方法,该方法继承ValidationProblemDetails,以返回所需的错误消息
首先,在startup.cs ConfigureServices
方法中添加以下代码:
services.AddMvc()
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var problems = new CustomBadRequest(context);
return new BadRequestObjectResult(problems);
};
});
以下是自定义错误请求方法:
public class CustomBadRequest : ValidationProblemDetails
{
public CustomBadRequest(ActionContext context)
{
Title = "Invalid arguments to the API";
Detail = "The inputs supplied to the API are invalid";
Status = 400;
ConstructErrorMessages(context);
Type = context.HttpContext.TraceIdentifier;
}
private void ConstructErrorMessages(ActionContext context)
{
foreach (var keyModelStatePair in context.ModelState)
{
var key = keyModelStatePair.Key.Replace("$.", "");
var errors = keyModelStatePair.Value.Errors;
if (errors != null && errors.Count > 0)
{
if (errors.Count == 1)
{
var errorMessage = GetErrorMessage(key, errors[0]);
Errors.Add(key, new[] { errorMessage });
}
else
{
var errorMessages = new string[errors.Count];
for (var i = 0; i < errors.Count; i++)
{
errorMessages[i] = GetErrorMessage(key,errors[i]);
}
Errors.Add(key, errorMessages);
}
}
}
}
string GetErrorMessage(string key, ModelError error)
{
if (error.ErrorMessage != $"The {key} field is required.")
{
return $"The {key} field is badly formed.";
}
return error.ErrorMessage;
}
}
公共类CustomBadRequest:ValidationProblemDetails
{
公共CustomBadRequest(ActionContext上下文)
{
Title=“API的参数无效”;
Detail=“提供给API的输入无效”;
状态=400;
构造错误消息(上下文);
Type=context.HttpContext.TraceIdentifier;
}
私有void构造函数错误消息(ActionContext上下文)
{
foreach(context.ModelState中的var keyModelStatePair)
{
var key=keyModelStatePair.key.Replace(“$”,”);
var errors=keyModelStatePair.Value.errors;
if(errors!=null&&errors.Count>0)
{
如果(errors.Count==1)
{
var errorMessage=GetErrorMessage(键,错误[0]);
添加(key,new[]{errorMessage});
}
其他的
{
var errorMessages=新字符串[errors.Count];
对于(变量i=0;iCustomBadRequest
方法,并通过判断返回相应的错误消息
以下是邮递员的测试结果:
这并不能解决问题。我相信[DataType]属性还有另一个用途。这是一个惊人的答案+1.