5

I have a custom filter attribute adapted from this answer currently implemented for .NET Core 2.2 that I would like to adapt to 3.1. It references Newtonsoft.JSON and I would prefer to keep it that way for compatibility reasons.

The code follows:

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 is only supported up to .net core 2.2, according to the official documentation; how should I proceed to keep the same behavior under 3.1?

OnoSendai
  • 3,960
  • 2
  • 22
  • 46
  • @MikeZboray thanks for the reply - my attempt at switching to the native formatter came to a stop when I learned that it behaved in a different way, ignoring properties from derived types when emitting JSON responses; this being the reason why I'm sticking with Newtonsoft.JSON, at least for the time being. More here: https://stackoverflow.com/questions/59308763/derived-types-properties-missing-in-json-response-from-asp-net-core-api – OnoSendai Jan 07 '20 at 19:18
  • 1
    Yes, I missed that you wanted to stay with newtonsoft for compatibility reasons. I think the Mvc.NewtonsoftJson package is where you want to look. Specifically, NewtonsoftJsonOutputFormatter seems to be the equivalent output formatter. – Mike Zboray Jan 07 '20 at 19:28
  • @MikeZboray I can't believe I missed that one - tried it and it worked flawlessly with some small changes. Would you post an answer so I can accept? – OnoSendai Jan 07 '20 at 19:35

3 Answers3

14

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)

This is only really affects the behavior via the SuppressOutputFormatterBuffering option. You might be able to resolve it from the RequestServices or you can just create a new one on the fly.

Mike Zboray
  • 39,828
  • 3
  • 90
  • 122
  • It's now depreciated, you need to add an additional parameter of `MvcNewtonsoftJsonOptions? jsonOptions` at the end per [link](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.formatters.newtonsoftjsonoutputformatter.-ctor?view=aspnetcore-7.0#microsoft-aspnetcore-mvc-formatters-newtonsoftjsonoutputformatter-ctor(newtonsoft-json-jsonserializersettings-system-buffers-arraypool((system-char))-microsoft-aspnetcore-mvc-mvcoptions-microsoft-aspnetcore-mvc-mvcnewtonsoftjsonoptions)) – kipras Aug 03 '23 at 02:21
4

The migration guide for Net Core 2.2 -> 3.0 has this information

Migration guide

The jist, you can use it you just have to manually add the package since its no longer included by default

  • Add a package reference to AspNetCore.Mvc.NewtonsoftJson
  • Add the following to your Startup.ConfigureServices method

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

  • 1
    Thanks Josh, that's quite close to that I have at initialization. My question have a slightly different focus - I'd like to have a different serialization behavior at controller level (i.e. a method that handles response serialization in a different way.) I still appreciate the time you took to answer though. – OnoSendai Jan 07 '20 at 19:21
4

.Net Core 3 brings with it its own JSON capabilities and does not include Json.Net anymore by default.

As an alternative, if this is possible, you can use the native SystemTextJsonOutputFormatter instead of including another package.

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
  • 2,581
  • 26
  • 35
  • Thanks for the answer, SanBen. I've ultimately decided to stick with NewtonsoftJson because of a design choice for JsonOutputFormatter - namely, it ignores properties from derived types. – OnoSendai Apr 06 '20 at 15:07