更改单个ASP.NET Core控制器的JSON序列化设置 [英] Change the JSON serialization settings of a single ASP.NET Core controller

查看:324
本文介绍了更改单个ASP.NET Core控制器的JSON序列化设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个控制器控制器:ControllerAControllerB.每个控制器的基类为Controller.

I'm having two controller controllers: ControllerA and ControllerB. The base class of each controller is Controller.

ControllerA需要以默认格式(camelCase)返回JSON. ControllerB需要以不同的JSON格式返回数据:snake_case.

The ControllerA needs to return JSON in the default format (camelCase). The ControllerB needs to return data in a different JSON format: snake_case.

如何在ASP.NET Core 3.x和2.1中实现呢?

How can I implement this in ASP.NET Core 3.x and 2.1?

我已经尝试过startup:

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

但这将更改所有控制器的序列化,而不仅仅是ControllerB.如何为1个控制器配置或注释此功能?

But this will change the serialization for all controllers, not just for ControllerB. How can I configure or annotate this feature for 1 controller?

推荐答案

您可以结合使用输出格式化程序.这是操作过滤器"外观的示例:

You can achieve this with a combination of an Action Filter and an Output 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>>()));
        }
    }
}

使用OnActionExecuted,代码将在相应的操作之后运行,并首先检查结果是否为ObjectResult(由于继承,该结果也适用于OkObjectResult).如果它是ObjectResult,则过滤器仅添加

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). If it is an ObjectResult, the filter simply adds a customised version of a JsonOutputFormatter that will serialise the properties using SnakeCaseNamingStrategy. The second parameter in the JsonOutputFormatter constructor is retrieved from the DI container.

要使用此过滤器,只需将其应用于相关的控制器:

In order to use this filter, just apply it to the relevant controller:

[SnakeCase]
public class ControllerB : Controller { }

ASP.NET Core 3.0+的更新

3.0+的情况看起来有些不同,其中3.0+的默认JSON格式器基于System.Text.Json.在撰写本文时,这些对蛇形命名策略没有内置支持.

Update for ASP.NET Core 3.0+

Things look a little different for 3.0+, where the default JSON-formatters for 3.0+ are based on System.Text.Json. At the time of writing, these don't have built-in support for a snake-case naming strategy.

但是,如果您将Json.NET与3.0+一起使用(有关详细信息,请参见

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:

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

代码如下:

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


注意:例如,您可能想在某个地方提前创建JsonOutputFormatter/NewtonsoftJsonOutputFormatter -在本示例中,我没有走那么远,因为这是手头问题的次要问题.


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.

这篇关于更改单个ASP.NET Core控制器的JSON序列化设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆