问题描述
在 .NET CORE 3.1 中构建 API,我需要验证 json 主体并将其反序列化为自定义类。 我为我的一个控制器所做的工作:
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
namespace MyNS
{
[JsonObject]
public class SearchAAA
{
[JsonProperty("query",required=required.Always)]
public Query Query { get; set; }
}
public class Query
{
[JsonProperty("and",required=required.Always)]
public List<And> And { get; set; }
}
public class And
{
[JsonProperty("property",required = required.Always)]
public string Property { get; set; }
[JsonProperty("operator",required = required.Always)]
public string Operator { get; set; }
[JsonProperty("value",required = required.Always)]
public object Value { get; set; }
}
}
接受的 json 应具有以下结构:
{
"query": {
"and": [
{
"operator": "eq","property": "prop1","value": "value1"
}
]
}
}
Controller1.cs
[Route("/v1/aaa/search")]
[HttpPost]
public async Task<JsonResult> Search(SearchAAA data)
{
foreach (var q in data.Query.And)
{
// ...
}
}
为了处理无效的 json,我在 Startup.cs
中添加了以下内容:
public void ConfigureServices(IServiceCollection services)
{
// [...]
services.AddControllers()
.AddNewtonsoftJson(options => {
//options.AllowInputFormatterExceptionMessages = false;
})
.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 };
};
});
services.AddAuthorization();
// [...]
}
这似乎有效,如果我发送无效的 json,我会收到如下示例所示的错误响应:
POST /v1/aaa/search
{
"query": {
"joker": [
{
"operator": "eq","value": "value1"
}
]
}
}
RESPONSE [400]
{
"success": false,"error": "Json property 'query.and': required property 'and' not found in JSON. Path 'query',line 10,position 3."
}
我正在尝试在新控制器中做同样的事情(需要将不同的 json 反序列化为不同的类对象)。无论出于何种原因我无法解释,都不会触发验证。使用调试器我只能看到无效的 json 将导致一个空的 data
字段,但 InvalidModelStateResponseFactory
没有被调用。我还注意到,在新控制器中(虽然与第一个基本相同),我需要添加一个 [FromBody]
属性以正确反序列化(而在第一个控制器中这不是必需的)。
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Microsoft.AspNetCore.Mvc;
namespace MyNS
{
[JsonObject]
public class SearchBBB
{
[JsonProperty("fields",required=required.Always)]
public List<Field> Fields { get; set; }
}
public class Field
{
[JsonProperty("property",required = required.Always)]
public string Property { get; set; }
[JsonProperty("value",required = required.Always)]
public object Value { get; set; }
}
}
Controller2.cs
[Route("/v1/bbb/search")]
[HttpPost]
public async Task<JsonResult> Search([FromBody] SearchBBB data)
{
foreach (var field in data.Fields)
{
// ...
}
}
即使我尝试在第二个控制器中重用类 SearchAAA
,我也不会收到验证错误:
Controller2.cs
[Route("/v1/bbb/search")]
[HttpPost]
public async Task<JsonResult> Search(SearchAAA data)
{
// ...
}
在我看来,对于同一应用程序的不同控制器,它应该以相同的方式工作,但事实并非如此。知道为什么吗?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)