【问题标题】:Newtonsoft.Json MVC: how customize DTO error message for failed json validationNewtonsoft.Json MVC:如何为失败的 json 验证自定义 DTO 错误消息
【发布时间】:2020-11-10 16:57:04
【问题描述】:

我在 .NET Core 3.1 上有一个 API 项目配置为使用 Newtonsoft.Json

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // [...]

    services.AddControllers().AddNewtonsoftJson();

    // [...]
}

Data.cs

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

namespace MyNS
{
    [JsonObject]
    public class MyData
    {
        [JsonProperty("query", Required=Required.Always)]
        public Query Query { get; set; }

        [JsonProperty("limit")]
        public int Limit { get; set; }
    }

    public class Query
    {
        [JsonProperty("props", Required=Required.Always)]
        public List<Prop> Props { get; set; }
    }

    public class Prop
    {
        // Allowed values should be only ("key1" and "key2"). Other strings or types should fail validation
        [JsonProperty("key", Required = Required.Always)]
        public string Key { get; set; }

        [JsonProperty("value", Required = Required.Always)]
        public string Value { get; set; }
    }
}

MyController.cs

// [...]
[Route("test")]
[HttpPost]
public async Task<JsonResult> Test(MyData data)
{
    return Json(data);
}
// [...]

如果请求 json 正文未通过验证,则会向客户端返回一个 400 状态的预配置错误消息:

REQUEST

POST /test
{
  "query": {
    "props": [
      {
        "key": "k1",
        "value": "v1"
      }
    ]
  },
  "limit": "wrong"
}

RESPONSE

{
    "errors": {
        "limit": [
            "Could not convert string to integer: wrong. Path 'limit', line 10, position 18."
        ]
    },
    "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
    "title": "One or more validation errors occurred.",
    "status": 400,
    "traceId": "|2778ea7e-4dff69c960e985d5."
}

我想使用我选择的 DTO 自定义错误响应,例如:
RESPONSE

"success": false,
"error": "First validation error"

如何配置 Newtonsoft.Json 以使用自定义 DTO 来处理验证错误?

【问题讨论】:

    标签: c# json .net api json.net


    【解决方案1】:

    找到可能的解决方案:

    Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers()
        .AddNewtonsoftJson(options => { })
        .ConfigureApiBehaviorOptions(options => {
            options.InvalidModelStateResponseFactory = context =>
            {
                string errorMessage = "Validation error";
    
                foreach (var key in context.ModelState.Keys)
                {
                    if (context.ModelState[key].Errors.Count > 0)
                    {
                        errorMessage = string.Format("Json property '{0}': {1}", key, context.ModelState[key].Errors[0].ErrorMessage);
                        break;
                    }
                }
    
                int statusCode = (int)HttpStatusCode.BadRequest;
    
                var dto = new
                {
                    success = false,
                    error = errorMessage
                };
    
                return new JsonResult(dto) { StatusCode = statusCode };
            };
        });
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-28
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      • 2012-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多