c# - ASP.NET Core 中的 SnakeCaseNamingStrategy 和 JsonPatch
问题描述
使用 ApsNetCore.JsonPatch (2.1.1) 包时,有没有办法注册/使用“全局”ContractResolver?
我遇到了路径未解析的问题,因为我的模型中的属性在 PascalCase 中,但 JsonPatch 中的路径在 SnakeCase 中。
在这种情况下,我必须将 JsonPatchDocument 上的 ContractResolver 设置为 Startup.cs 文件中的默认/全局注册的 ContractResolver。
它有效,但我必须为我要实施的每个补丁路由都这样做。
启动配置:
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services
.AddJsonOptions(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
})
}
控制器:
[HttpPatch("{id}"]
[Consumes(MediaTypeNames.Application.Json)]
public async Task<IActionResult> Patch(string id,
[FromBody] JsonPatchDocument<Entity> patchEntity)
{
...
patchEntity.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
patchEntity.ApplyTo(entity);
...
解决方案
似乎没有简单的方法来影响ContractResolver
创建JsonPatchDocument<T>
. 此类的实例由 a 创建TypedJsonPatchDocumentConverter
,如下代码片段所示:
var container = Activator.CreateInstance(
objectType,
targetOperations,
new DefaultContractResolver());
很明显,DefaultContractResolver
在创建JsonPatchDocument<T>
.
使用 ASP.NET Core MVC 时处理此问题的一种选择是使用Action Filter,它允许对传递给操作的任何参数进行更改。这是一个基本示例:
public class ExampleActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext ctx)
{
// Find a single argument we can treat as IJsonPatchDocument.
var jsonPatchDocumentActionArgument = ctx.ActionArguments.SingleOrDefault(
x => typeof(IJsonPatchDocument).IsAssignableFrom(x.Value.GetType()));
// Here, jsonPatchDocumentActionArgument.Value will be null if none was found.
var jsonPatchDocument = jsonPatchDocumentActionArgument.Value as IJsonPatchDocument;
if (jsonPatchDocument != null)
{
jsonPatchDocument.ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy()
};
}
}
}
ActionExecutingContext
此处传入的类包含一个ActionArguments
属性,在此示例中用于尝试查找类型为 的参数IJsonPatchDocument
。如果找到一个,我们会ContractResolver
相应地覆盖它。
为了使用这个新的动作过滤器,您可以将它添加到控制器、动作或全局注册它。以下是如何在全球范围内注册它(其他选项有很多答案,所以我不会在这里深入探讨):
services.AddMvc(options =>
{
options.Filters.Add(new ExampleActionFilterAttribute());
});
推荐阅读
- javascript - 如何在 React JS 中一次更新状态变量
- python - 从多个不同大小的数据集加载 PyTorch 数据
- r - apply() 没有按预期工作
- python - 无法在 Pycharm 中执行“manage.py”命令
- c# - 任务中的属性值不同
- sqlite - 在 docker 容器中运行 go binary 时找不到 Spatialite 扩展
- c++ - 在谷歌测试中检测分离线程调用exit(0)
- sql - ERD UML 建议 (SQL)
- search - 访问 Google 搜索结果的最后一页
- mysql - 如何使用 GROUP_CONCAT 动态旋转和生成串联列名