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

强颜欢笑 提交于 2019-12-21 07:29:46

问题


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

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

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

I've tried the startup with:

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. How can I configure or annotate this feature for 1 controller?


回答1:


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

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

Note: You might want to create the JsonOutputFormatter ahead of time somewhere, for example - I've not gone that far in the example as that's secondary to the question at hand.



来源:https://stackoverflow.com/questions/52605946/change-the-json-serialization-settings-of-a-single-asp-net-core-controller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!