Custom OutputFormatters in ASP.NET Core 3.0

Ikechi Michael
2 min readOct 6, 2019

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.

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.

--

--

Ikechi Michael

I’ve learned I don’t know anything. I've also learned that people will pay for what I know. Maybe that's why they never pay.