简体   繁体   English

更改单个 ASP.NET Core 控制器的 JSON 序列化设置

[英]Change the JSON serialization settings of a single ASP.NET Core controller

I'm having two controller controllers: ControllerA and ControllerB .我有两个控制器控制器: ControllerAControllerB The base class of each controller is Controller .每个控制器的基类是Controller

The ControllerA needs to return JSON in the default format (camelCase). ControllerA需要以默认格式(驼峰式大小写)返回 JSON。 The ControllerB needs to return data in a different JSON format: snake_case. ControllerB需要以不同的 JSON 格式返回数据:snake_case。

How can I implement this in ASP.NET Core 3.x and 2.1?如何在 ASP.NET Core 3.x 和 2.1 中实现这一点?

I've tried the startup with:我试过startup

services
    .AddMvc()
    .AddJsonOptions(options =>
    {
        options.SerializerSettings.Converters.Add(new StringEnumConverter());
        options.SerializerSettings.ContractResolver = new DefaultContractResolver()
        {
            NamingStrategy = new SnakeCaseNamingStrategy()
        };
    })
    .AddControllersAsServices();

But this will change the serialization for all controllers, not just for ControllerB .但这将改变所有控制器的序列化,而不仅仅是ControllerB How can I configure or annotate this feature for 1 controller?如何为 1 个控制器配置或注释此功能?

ASP.NET Core 3.0+ ASP.NET 核心 3.0+

You can achieve this with a combination of an Action Filter and an Output Formatter .您可以使用Action FilterOutput Formatter的组合来实现这一点。

Things look a little different for 3.0+, where the default JSON-formatters for 3.0+ are based on System.Text.Json . 3.0+ 的情况看起来有点不同,3.0+ 的默认 JSON 格式器基于System.Text.Json At the time of writing, these don't have built-in support for a snake-case naming strategy .在撰写本文时,这些还没有对蛇形命名策略的内置支持

However, if you're using Json.NET with 3.0+ (details in the docs ), the SnakeCaseAttribute from above is still viable, with a couple of changes:但是,如果您将 Json.NET 与 3.0+( 文档中的详细信息)一起使用,则上面的SnakeCaseAttribute仍然可行,但有一些更改:

  1. JsonOutputFormatter is now NewtonsoftJsonOutputFormatter . JsonOutputFormatter现在是NewtonsoftJsonOutputFormatter
  2. The NewtonsoftJsonOutputFormatter constructor requires an argument of MvcOptions . NewtonsoftJsonOutputFormatter构造函数需要一个MvcOptions参数。

Here's the code:这是代码:

public class SnakeCaseAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext ctx)
    {
        if (ctx.Result is ObjectResult objectResult)
        {
            objectResult.Formatters.Add(new NewtonsoftJsonOutputFormatter(
                new JsonSerializerSettings
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new SnakeCaseNamingStrategy()
                    }
                },
                ctx.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>(),
                ctx.HttpContext.RequestServices.GetRequiredService<IOptions<MvcOptions>>().Value));
        }
    }
}

ASP.NET Core 2.x ASP.NET 核心 2.x

You can achieve this with a combination of an Action Filter and an Output Formatter .您可以使用Action FilterOutput Formatter的组合来实现这一点。 Here's an example of what the Action Filter might look like:以下是操作过滤器的外观示例:

public class SnakeCaseAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext ctx)
    {
        if (ctx.Result is ObjectResult objectResult)
        {
            objectResult.Formatters.Add(new JsonOutputFormatter(
                new JsonSerializerSettings
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new SnakeCaseNamingStrategy()
                    }
                },
                ctx.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>()));
        }
    }
}

Using OnActionExecuted , the code runs after the corresponding action and first checks to see if the result is an ObjectResult (which also applies to OkObjectResult thanks to inheritance).使用OnActionExecuted ,代码在相应的操作之后运行,并首先检查结果是否为ObjectResult (由于继承,这也适用于OkObjectResult )。 If it is an ObjectResult , the filter simply adds a customised version of a JsonOutputFormatter that will serialise the properties using SnakeCaseNamingStrategy .如果它是ObjectResult ,过滤器只需添加一个JsonOutputFormatter的自定义版本,该版本将使用SnakeCaseNamingStrategy序列化属性。 The second parameter in the JsonOutputFormatter constructor is retrieved from the DI container. JsonOutputFormatter构造函数中的第二个参数是从 DI 容器中检索的。

In order to use this filter, just apply it to the relevant controller:为了使用这个过滤器,只需将它应用到相关的控制器:

[SnakeCase]
public class ControllerB : Controller { }

Note: You might want to create the JsonOutputFormatter / NewtonsoftJsonOutputFormatter ahead of time somewhere, for example - I've not gone that far in the example as that's secondary to the question at hand.注意:例如,您可能希望在某处提前创建JsonOutputFormatter / NewtonsoftJsonOutputFormatter - 我在示例中没有走那么远,因为这是手头问题的次要问题。

Ended up creating this method that I use on my end points:最终创建了我在端点上使用的这个方法:

{           
    // needed to get the same date and property formatting 
    // as the Search Service:
    var settings = new JsonSerializerSettings
    {
        ContractResolver = new DefaultContractResolver()
        {
            NamingStrategy = new SnakeCaseNamingStrategy()
        },
        DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffZ"
    };

    return Json(result, settings);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 ASP.NET Core 3 中更改单个 ASP.NET Core API 控制器或单个操作的 System.Text.Json 序列化选项 - Change System.Text.Json Serialization Options of a single ASP.NET Core API controller or single Action in ASP.NET Core 3 更改单个 ASP.NET 内核 controller 的 JSON 反序列化/序列化策略 - Change the JSON deserialization/serialization policy for single ASP.NET Core controller ASP.NET Core 中每个控制器的不同 JSON 反序列化设置 - Different JSON deserialization settings per controller in ASP.NET Core ASP.Net Core 中的 JSON 序列化/反序列化 - JSON serialization/deserialization in ASP.Net Core 在 ASP.NET Core 中更改控制器路由 - Change Controller Route in ASP.NET Core 更改或禁用ASP.NET Web窗体上的默认JSON序列化 - change or disable default json serialization on an asp.net webform ASP.NET Core appsettings.json 未加载正确的设置 - ASP.NET Core appsettings.json not loading the correct settings 如何在 asp.net 内核 3 中设置 json 串行器设置? - How to set json serializer settings in asp.net core 3? ASP.NET MVC 6上每个控制器的特定JSON设置 - Specific JSON settings per controller on ASP.NET MVC 6 更改JSON.NET序列化设置 - Change JSON.NET Serialization Settings
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM