C# ASP.NET内核中的SnakeCaseNamingStrategy和JsonPatch

C# ASP.NET内核中的SnakeCaseNamingStrategy和JsonPatch,c#,asp.net-core,json-patch,C#,Asp.net Core,Json Patch,在使用时是否有方法注册/使用“全局”ContractResolver ApsNetCore.JsonPatch(2.1.1)包 我遇到了一个问题,路径没有得到解决,因为我的模型中的属性在PascalCase中,而JsonPatch中的路径在SnakeCase中 在这种情况下,我必须在Startup.cs文件中将JsonPatchDocument上的ContractResolver设置为默认/全局注册的ContractResolver 它可以工作,但我必须为我要实现的每个补丁路径都这样做 启动配置

在使用时是否有方法注册/使用“全局”ContractResolver ApsNetCore.JsonPatch(2.1.1)包

我遇到了一个问题,路径没有得到解决,因为我的模型中的属性在PascalCase中,而JsonPatch中的路径在SnakeCase中

在这种情况下,我必须在Startup.cs文件中将JsonPatchDocument上的ContractResolver设置为默认/全局注册的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);
    ...
[HttpPatch({id}]
[使用(MediaTypeNames.Application.Json)]
公共异步任务修补程序(字符串id,
[FromBody]JsonPatchDocument patchEntity)
{
...
patchEntity.ContractResolver=新的DefaultContractResolver
{
NamingStrategy=新的蛇案例NamingStrategy()
};
patchEntity.ApplyTo(实体);
...

似乎没有简单的方法可以影响创建
JsonPatchDocument
实例时使用的
ContractResolver

var container = Activator.CreateInstance(
    objectType,
    targetOperations,
    new DefaultContractResolver());
这里很清楚,在创建
JsonPatchDocument
的实例时,
DefaultContractResolver
被硬编码为第二个参数

使用ASP.NET Core MVC时处理此问题的一个选项是使用,它允许对传递到操作中的任何参数进行更改。下面是一个基本示例:

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