ASP.NET Core 3.0+
您可以通过Action Filter 和Output Formatter 的组合来实现此目的。
3.0+ 的情况看起来有些不同,其中 3.0+ 的默认 JSON 格式化程序基于 System.Text.Json。在撰写本文时,这些don't have built-in support for a snake-case naming strategy。
但是,如果您使用 3.0+ 的 Json.NET(详细信息在 docs 中),则上面的 SnakeCaseAttribute 仍然可行,但需要进行一些更改:
-
JsonOutputFormatter 现在是 NewtonsoftJsonOutputFormatter。
-
NewtonsoftJsonOutputFormatter 构造函数需要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 Core 2.x
您可以通过Action Filter 和Output 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>>()));
}
}
}
使用OnActionExecuted,代码在相应操作之后运行,并首先检查结果是否为ObjectResult(由于继承,这也适用于OkObjectResult)。如果是ObjectResult,过滤器只需添加JsonOutputFormatter 的自定义版本,它将使用SnakeCaseNamingStrategy 序列化属性。 JsonOutputFormatter 构造函数中的第二个参数是从 DI 容器中获取的。
要使用此过滤器,只需将其应用于相关控制器:
[SnakeCase]
public class ControllerB : Controller { }
注意:例如,您可能希望在某个地方提前创建 JsonOutputFormatter/NewtonsoftJsonOutputFormatter - 我在示例中没有走那么远,因为这是手头问题的次要问题。