I'm very confused at the moment with a basic ASP.NET Core 2 API project and content negotiation and returning something other than JSON.
I've had this working before in a 1.1 project but not in a 2. I basically want to return something either as JSON or XML depending on request type.
As part of that requirement I set up the XML formatter like so:
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc(options =>
{
options.ReturnHttpNotAcceptable = true;
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
}
I could also use AddXmlSerializerFormatters()
but same difference (and tried). This is the way I've seen in countless examples and done before.
I have a single controller and single action, basically looks like:
[Route("api/[controller]")]
public class DefaultController : Controller
{
[HttpGet]
[Route("")]
public IActionResult Index()
{
return Ok(new
{
success = true
});
}
}
Now when I run I get this back in Postman:
{"success": true}
So it works (or at least defaults) to JSON.
Then if I request using the header Accept: application/xml
instead I now get a HTTP error of 406.
If I take off options.ReturnHttpNotAcceptable = true;
, it will return JSON regardless.
What am I missing? I'm sat scratching my head on this. As far as I know I've registered an acceptable content formatter.
The problem you are seeing is that anonymous types cannot be serialized into XML, so the formatter fails and falls back to the JSON formatter.
Solution: use classes when you need to return XML.
There is already open issue for that.
As a workaround try adding this option to Mvc:
options.FormatterMappings.SetMediaTypeMappingForFormat("xml", "text/xml");
with [FormatFilter] attribute
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With