如何手动反序列化ModelStateDictionary

时间:2017-01-02 11:37:38

标签: c# asp.net-core asp.net-core-mvc

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

    {
        "message": "Validation errors in your request",
        "errors": {
            "email": [
                  "The Email is required"
                ],
            "Address": [
                  "The Address is required"
                ]
        }
    }

在我尝试使用以下内容的过滤器中:

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

生成的响应格式为:

{
    "Email": [
          "The Email is required"
        ],
    "Address": [
          "The Address is required"
        ]
}

缺少message属性和errors信封。我尝试了很多方法,但它没有用。 e.g。

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);
            }
        }
    }

但是响应包含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
    }
  }
}

1 个答案:

答案 0 :(得分:3)

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

让我们先来看一下BadRequestObjectResult课程(来源here

public BadRequestObjectResult(ModelStateDictionary modelState)
        : base(new SerializableError(modelState))
{
}

正如我们所看到的,ModelStateDictionary的覆盖将模型状态传递给新的类SerializableError,然后将其传递给基类。

当我们查看SerializableError我们看到的source时,它是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);
        }
    }
}

这应该有用(没有测试)。