c# - Newtonsoft.Json MVC:如何为失败的 json 验证自定义 DTO 错误消息
问题描述
我在.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 来处理验证错误?
解决方案
找到了一个可能的解决方案:
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 };
};
});
}
推荐阅读
- svg - Safari MacOS 外来对象在 svg 中未正确缩放
- c++ - 两个进程绑定并监听相同的地址和端口,但是如何确保它们都能接收到传入的消息?
- python - 将 pandas df 列中的值除以数字
- java - 多个线程中的实例对象是否可以访问相同的静态类和变量?
- pycharm - PyCharm:当光标移过它们时,有没有办法阻止代码折叠自动展开?
- android - 无法使用用 futter 编写的 firebase 在应用程序中进行 google 身份验证
- google-apps-script - 如何检测来自多个电子表格的编辑
- pandas - 我想在熊猫系列中用 1- 替换 $,我该怎么做
- html - 覆盖 PrimeReact 样式
- javascript - 基于类型更改对象到javascript中的嵌套数组