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

5

我有一个自定义的过滤器属性,它改编自这个答案,目前已经在.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,根据官方文档;如果我想在3.1下保持相同的行为,应该如何操作?


@MikeZboray 感谢您的回复 - 当我尝试切换到本地格式化程序时,我发现它的行为方式不同,当发出JSON响应时会忽略派生类型的属性; 这就是为什么我目前仍然坚持使用Newtonsoft.JSON的原因。更多信息请参见:https://dev59.com/F1IH5IYBdhLWcg3wgvGx - OnoSendai
1
是的,我错过了您想为兼容性原因继续使用newtonsoft。我认为Mvc.NewtonsoftJson包是您想要查找的地方。具体来说,NewtonsoftJsonOutputFormatter似乎是等效的输出格式化程序。 - Mike Zboray
@MikeZboray,我简直不敢相信我错过了那个 - 我试了一下,只做了一些小改动就完美地运行了。你能发一个答案让我采纳吗? - OnoSendai
3个回答

14

旧的JsonOutputFormatter对应的是Microsoft.AspNetCore.Mvc.NewtonsoftJson包中的NewtonsoftJsonOutputFormatter。它只有一个小改变,在构造函数中也会接受MvcOptions:

The equivalent of the old JsonOutputFormatter is NewtonsoftJsonOutputFormatter in the Microsoft.AspNetCore.Mvc.NewtonsoftJson package. It has one minor change, where it will accept an MvcOptions in the constructor as well:

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

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


现在已经被弃用,您需要在结尾添加一个额外的参数 MvcNewtonsoftJsonOptions? jsonOptions,请参考链接 - kipras

4

.Net Core 3带来了自己的JSON功能,默认情况下不再包含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);
}

感谢您的回答,SanBen。我最终决定坚持使用NewtonsoftJson,因为JsonOutputFormatter的设计选择忽略了派生类型的属性。 - OnoSendai

4
Net Core 2.2 -> 3.0的迁移指南包含以下信息: 迁移指南 简而言之,您可以使用它,只需手动添加包,因为它不再默认包含在其中。
  • Add a package reference to AspNetCore.Mvc.NewtonsoftJson
  • Add the following to your Startup.ConfigureServices method

      services.AddMvc()
          .AddNewtonsoftJson();
    
  • Configure


1
谢谢Josh,这很接近我在初始化时的情况。我的问题有稍微不同的重点 - 我想在控制器级别(即以不同方式处理响应序列化的方法)拥有不同的序列化行为。尽管如此,我仍然感谢你花费的时间来回答我的问题。 - OnoSendai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接