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

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

问题描述

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

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

ControllerA 需要以默认格式(驼峰式大小写)返回 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?

推荐答案

ASP.NET Core 3.0+

您可以通过 操作过滤器输出格式化程序.

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

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+(docs),上面的 SnakeCaseAttribute 仍然可行,有几个变化:

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

ASP.NET 核心 2.x

您可以通过 操作过滤器输出格式化程序.以下是操作过滤器的外观示例:

ASP.NET Core 2.x

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,过滤器只需添加一个自定义版本的 JsonOutputFormatter 将使用 SnakeCaseNamingStrategy 序列化属性.JsonOutputFormatter 构造函数中的第二个参数是从 DI 容器中检索的.

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 { }

<小时>

注意:例如,您可能希望在某处提前创建 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天全站免登陆