自定义 ASP.NET Core MVC 验证响应

Ali*_*ani 5 validation asp.net-core-mvc asp.net-core

ASP.NET Core MVC 具有出色的模型绑定和模型验证子系统,几乎支持任何场景。但开发API时,事情可能会变得更复杂一些。

假设我们有一个模型类,XYZ其属性用 注释[MinLength(5)]

public class ViewModel
{
    [MinLength(5)]
    public string XYZ { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

如果此属性出现任何问题,MVC 将为您提供如下所示的内容:

{ "XYZ": [ "The field XYZ must be a string or array type with minimum length of '5'" ] }
Run Code Online (Sandbox Code Playgroud)

但这不是客户需要的!客户需要一个具有特定细节的对象。她将根据自己的意愿创建自己的消息:

{ "error": "minLength", "property": "XYZ", "minimum": 5 }
Run Code Online (Sandbox Code Playgroud)

可能的解决方案:

  1. 您可以使用它InvalidModelStateResponseFactory来生成自定义响应。它为您提供ActionContext包含该ModelState属性的 。但你所能做的就是处理纯字符串的错误消息!这可能会导致一些问题。
  2. 另一种选择是完全禁用 MVC 验证并自己实现一个。

我很感激任何其他解决方案。

Tao*_*hou 2

对于一般验证消息,它是纯字符串。对于不同的验证属性,forminLength和是不同的。minimum我想知道客户端如何检查不同的节点。

对于服务器端,InvalidModelStateResponseFactory最好返回 json 对象。并且您需要检查 ValidationAttribute 是否返回不同的对象,例如

services.Configure<ApiBehaviorOptions>(o =>
{
    o.InvalidModelStateResponseFactory = actionContext =>
    {
        var error = new Dictionary<string, string>();
        foreach (var key in actionContext.ModelState.Keys)
        {
            foreach (var parameter in actionContext.ActionDescriptor.Parameters)
            {
                var prop = parameter.ParameterType.GetProperty(key);
                if (prop != null)
                {
                    var attr = prop.GetCustomAttributes(typeof(ValidationAttribute), false).FirstOrDefault() as ValidationAttribute;
                    if (attr is MinLengthAttribute minLengthAttribute)
                    {
                        error.Add("Error", "minLength");
                        error.Add("Property", key);
                        error.Add("minimum", minLengthAttribute.Length.ToString());    
                    }
                }
            }
        }
        return new BadRequestObjectResult(error);
    };
});
Run Code Online (Sandbox Code Playgroud)