Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot serialise to XML in ASP.NET Core 2

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.

like image 374
Lloyd Avatar asked Dec 23 '17 16:12

Lloyd


2 Answers

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.

like image 63
Camilo Terevinto Avatar answered Sep 21 '22 23:09

Camilo Terevinto


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

like image 22
zxczzx Avatar answered Sep 24 '22 23:09

zxczzx