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

Kee*_*ker 12 c# json.net asp.net-core-mvc .net-core asp.net-core

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

ControllerA需要的默认格式(驼峰)返回JSON。将ControllerB需要在不同的JSON格式返回数据:snake_case。

如何在ASP.NET Core 2.1中实现此功能?

我已经尝试过startup

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

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

Kir*_*kin 9

您可以结合使用Action FilterOutput Formatter来实现。这是一个动作过滤器外观示例:

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>>()));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用OnActionExecuted,代码将在相应的操作之后运行,并首先检查结果是否为ObjectResult(也适用OkObjectResult于继承)。如果为ObjectResult,则过滤器仅添加的自定义版本,JsonOutputFormatter即可使用序列化属性SnakeCaseNamingStrategyJsonOutputFormatter从DI容器中检索构造函数中的第二个参数。

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

[SnakeCase]
public class ControllerB : Controller { }
Run Code Online (Sandbox Code Playgroud)

注意:例如,您可能想JsonOutputFormatter提前创建某个位置-在本示例中,我没有走那么远,因为这是眼前的问题。


Ale*_*lex 5

不需要动作过滤器等​​。只需Json()在控制器中覆盖即可。

public class MyController : Controller
{
    public override JsonResult Json(object data)
    {
        return base.Json(data, new JsonSerializerSettings {
            // set whataever default options you want
        });
    }
}
Run Code Online (Sandbox Code Playgroud)