ASP.NET Core 3.1 控制器级别的 JsonOutputFormatter 替代方案

Alternatives to JsonOutputFormatter in ASP.NET Core 3.1 at Controller Level

我有一个自定义过滤器属性,该属性改编自 目前为 .NET Core 2.2 实施,我想适应 3.1。它引用 Newtonsoft.JSON,出于兼容性原因,我更愿意保持这种方式。

代码如下:

public class AllPropertiesAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext ctx)
    {
        if (!(ctx.Result is ObjectResult objectResult)) return;

        var serializer = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Include };
        serializer.Converters.Add(new StringEnumConverter());

        var formatter = new JsonOutputFormatter(serializer, 
                        ctx.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>());

        objectResult.Formatters.Add(formatter);
    }
}

JsonOutputFormatter 仅支持 .net core 2.2,according to the official documentation;我应该如何继续在 3.1 下保持相同的行为?

Net Core 2.2 -> 3.0 的迁移指南有此信息

Migration guide

jist,你可以使用它,你只需要手动添加包,因为它不再默认包含

  • 添加对 AspNetCore.Mvc.NewtonsoftJson
  • 的包引用
  • 将以下内容添加到您的 Startup.ConfigureServices 方法中

      services.AddMvc()
          .AddNewtonsoftJson();
    
  • 配置

旧 JsonOutputFormatter 的等效项是 Microsoft.AspNetCore.Mvc.NewtonsoftJson 包中的 NewtonsoftJsonOutputFormatter。它有一个小的变化,它也将在构造函数中接受一个 MvcOptions:

    public NewtonsoftJsonOutputFormatter(
        JsonSerializerSettings serializerSettings,
        ArrayPool<char> charPool,
        MvcOptions mvcOptions)

这只会真正影响 SuppressOutputFormatterBuffering 选项的行为。您也许可以从 RequestServices 中解决它,或者您可以即时创建一个新的。

.Net Core 3 自带its own JSON capabilities,默认不再包含Json.Net。

作为替代方案,如果可能的话,您可以使用本机 SystemTextJsonOutputFormatter 而不是包含另一个包。

using Microsoft.AspNetCore.Mvc.Formatters;

public override void OnActionExecuted(ActionExecutedContext ctx)
{
    if (!(ctx.Result is ObjectResult objectResult)) return;

    var serializer = new JsonSerializerOptions { IgnoreNullValues = false };
    serializer.Converters.Add(new JsonStringEnumConverter());

    var formatter = new SystemTextJsonOutputFormatter(serializer);

    objectResult.Formatters.Add(formatter);
}