簡體   English   中英

Newtonsoft.Json MVC:如何為失敗的 json 驗證自定義 DTO 錯誤消息

[英]Newtonsoft.Json MVC: how customize DTO error message for failed json validation

我在.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 body 驗證失敗,則會向客戶端返回一條預配置的 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 來處理驗證錯誤?

找到了一個可能的解決方案:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM