Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 一致输入模型验证错误报告_Asp.net_.net_Asp.net Core_Asp.net Core Webapi_Asp.net Core 3.1 - Fatal编程技术网

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;i 完成上述设置后,当您的InputModel非法时,会自动进入
CustomBadRequest
方法,并通过判断返回相应的错误消息

以下是邮递员的测试结果:


这并不能解决问题。我相信[DataType]属性还有另一个用途。这是一个惊人的答案+1.