Custom OutputFormatters in ASP.NET Core 3.0
Today, I faced the nastiest bug 🐜 in my code, when upgrading a Web API project from 2.2. to 3.0.
The API response was consistently an MS Excel file, no matter what the request’s Accept header was.
I knew the API had multiple output formatters, and it worked well in 2.2, so what could be wrong? My MVC setup in my Startup.cs looked like:
You might have noticed that Mykeels.ExcelOutputFormatter
is first added to the OutputFormatters
property in the MVC options.
This turned out to be the reason, and it was surprising because it was never a problem before.
You see, in asp.net 2.2, we used:
services.AddMvc(...)
.AddJsonOptions(...);
and I assume it would automatically place a JSON formatter, powered by Newtonsoft.Json, as the default formatter.
But now, dotnet has its own JSON library inbuilt, called System.Text.Json
, which is supposed to be really powerful. That means, AddJsonOptions
no longer adds a formatter powered by Newtonsoft.Json, but one powered by System.Text.Json
. Which is why we use AddNewtonsoftJson(...)
instead.
But AddNewtonsoftJson(...)
does not seem to register the JSON formatter as the default, because it comes right after our custom formatters are registered.
The way out, is to register it first, before our custom formatters, using:
services.AddControllers()
.AddNewtonsoftJson(...);
Right before:
services.AddMvc(options => {
options.OutputFormatters.Add(...);
})
So the working code becomes:
Which fixes the issue.
Now, if there’s no Accept
header present, I get a JSON
response as expected, and an appropriate response if the header value is text/csv
or application/ms-excel
.
My upgrade bug woes aren’t over, but at least this battle is won.