如何手动反序列化 ModelStateDictionary

adn*_*ili 2 c# asp.net-core-mvc asp.net-core

我正在尝试处理过滤器中的验证错误。验证响应格式应类似于:

    {
        "message": "Validation errors in your request",
        "errors": {
            "email": [
                  "The Email is required"
                ],
            "Address": [
                  "The Address is required"
                ]
        }
    }
Run Code Online (Sandbox Code Playgroud)

在我尝试以下操作时的过滤器中:

public override void OnActionExecuting(ActionExecutingContext context)
{
    if (!context.ModelState.IsValid)
    {
        context.Result = new BadRequestObjectResult(context.ModelState);
    }
}
Run Code Online (Sandbox Code Playgroud)

生成的响应格式为:

{
    "Email": [
          "The Email is required"
        ],
    "Address": [
          "The Address is required"
        ]
}
Run Code Online (Sandbox Code Playgroud)

message财产和errors信封不见了。我尝试了很多方法,但没有奏效。例如

public class ValidateModelAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            if (!context.ModelState.IsValid)
            {
                var validationErrorResponse = new Dictionary<string, Object>();
                validationErrorResponse["message"] = "The request has validation errors";
                validationErrorResponse["errors"] = context.ModelState;
                context.Result = new BadRequestObjectResult(validationErrorResponse);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是 response 包含了 modeldictionary 的所有属性:

{
  "message": "The request has validation errors",
  "errors": {
    "Name": {
      "childNodes": null,
      "children": null,
      "key": "Name",
      "subKey": {
        "buffer": "Name",
        "offset": 0,
        "length": 4,
        "value": "Name",
        "hasValue": true
      },
      "isContainerNode": false,
      "rawValue": null,
      "attemptedValue": null,
      "errors": [
        {
          "exception": null,
          "errorMessage": "The Name field is required."
        }
      ],
      "validationState": 1
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Tse*_*eng 5

ASP.NET Core 的优势在于它是开源的,您可以随时查看代码并了解它的作用;)

我们先来看看BadRequestObjectResult类(来源在这里

public BadRequestObjectResult(ModelStateDictionary modelState)
        : base(new SerializableError(modelState))
{
}
Run Code Online (Sandbox Code Playgroud)

如我们所见,覆盖 forModelStateDictionary将模型状态SerializableError传递给一个新类,然后传递给基类。

当我们查看我们看到的源代码SerializableError,它是一个围绕 an 的包装器IDictionary<string,object>,可以很好地格式化消息。

话虽如此,这是您需要使用的代码:

public class ValidateModelAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext context)
    {
        if (!context.ModelState.IsValid)
        {
            var validationErrorResponse = new Dictionary<string, Object>();
            validationErrorResponse["message"] = "The request has validation errors";
            validationErrorResponse["errors"] = new SerializableError(context.ModelState);
            context.Result = new BadRequestObjectResult(validationErrorResponse);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

那应该工作(没有测试)。