Search code examples
c#asp.net-core-mvcautofac

Using FormatFilter attribute within mvc core 2.1.3 API


I'm facing som difficulties getting the [FormatFilter] to work in my MVC Core 2.1.3 API. I want my endpoint to support JSON and XML, so I wrote this code:

Startup class, which inherits from a StartupCore class:

public class Startup : StartupCore
{
    protected override void OnConfigure(
        IApplicationBuilder app,
        IHostingEnvironment env,
        ILoggerFactory loggerFactory,
        IApplicationLifetime appLifetime) => AutoMappings.Initialize();
}

And (partially) this StartupCore class

//....
services
    .AddCors()
    .AddMvcCore()
    .AddApiExplorer()
    .AddJsonFormatters()
    .AddXmlSerializerFormatters() //With or without this line; no luck
    .AddJsonOptions(options =>
    {
        options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
    })
    .AddMvcOptions(options =>
    {
        options.InputFormatters.Add(new PlainTextInputFormatter());
        options.OutputFormatters.Add(new CsvOutputFormatter());
        options.FormatterMappings.SetMediaTypeMappingForFormat("csv", MediaTypeHeaderValue.Parse("text/csv"));
        options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
        options.FormatterMappings.SetMediaTypeMappingForFormat("xml", MediaTypeHeaderValue.Parse("application/xml"));
    })
//.......

When I use the FormatFilter attribute on my controller like

[HttpGet]
[FormatFilter]
[Route("/public/feed/{format}")]
public async Task<IActionResult> CreateFeed(string format)
{
    //
}

I'm getting the error: Autofac.Core.Registration.ComponentNotRegisteredException: The requested service 'Microsoft.AspNetCore.Mvc.Formatters.FormatFilter' has not been registered.

However when I use the Produces attribute it gives me XML data.

[HttpGet]
[Produces("application/xml")]
[Route("/public/feed/{format}")]
public async Task<IActionResult> CreateFeed(string format)
{
    //
}

I could end up with two endpoints; one for JSON and one for XML but I rather have one endpoint with the FormatFilter.

So what am I missing here?

WORKAROUND: For now I'm using the Produces attribute [Produces("application/json", "application/xml"]

Source used: https://andrewlock.net/formatting-response-data-as-xml-or-json-based-on-the-url-in-asp-net-core/


Solution

  • If endpoint or controller uses FormatFilter attribute then the corresponding service should be registered via AddFormatterMappings:

    services.AddMvcCore()
    ...
    .AddFormatterMappings()