Problem
This post will show you how to accept and return data in different formats in ASP.NET Core Web API.
Solution
In the previously created CRUD sample, update Startup
class to add input and output formatter for XML:
public void ConfigureServices(
IServiceCollection services)
{
services.AddSingleton<IMovieService, MovieService>();
services.AddMvc(options =>
{
options.InputFormatters.Add(new XmlSerializerInputFormatter());
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
}
Try a GET
request with Accept
header of application/xml:
![Image 1](/KB/webservices/1204319/get-1.png)
Try a POST
request with Content-Type
header of application/xml:
![Image 2](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Discussion
Framework uses JSON
by default to serialise input and format responses containing custom models. We can configure formatters for both input (to serialise incoming data) and output (to format responses) in AddMvc()
method, using InputFormatters
and OutputFormatters
collections.
Content Negotiation
To receive data from the server, client will specify the format it can process in Accept
HTTP header. If the server has a suitable formatter, it will use it to format the response. This process is known as content negotiation.
If a suitable formatter doesn’t exist, framework will use the default JSON
formatter. You could configure the server to return 406 (Not Acceptable)
status code response instead:
services.AddMvc(options =>
{
options.ReturnHttpNotAcceptable = true;
options.InputFormatters.Add(new XmlSerializerInputFormatter());
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
When sending data to server, Content-Type
header specifies the type of data in HTTP body. If a suitable input formatter is not setup, server will return 415 (Unsupported Media Type)
response. To demonstrate this, comment out the line that adds input formatter and try POST
:
![Image 3](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
Removing Formatters
You could remove default formatters as well, e.g. by default 204 (No Content)
status code is returned for null
responses. You could remove the default formatter for this behaviour, which will return 200 (OK)
instead:
services.AddMvc(options =>
{
options.ReturnHttpNotAcceptable = true;
options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
options.InputFormatters.Add(new XmlSerializerInputFormatter());
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
});
Format Filter
An alternate method of content negotiation and specifying the format of data client can accept is that you use [FormatFilter]
filter attribute and have format (e.g. XML) in URL:
[HttpGet()]
[HttpGet("/movies.{format}"), FormatFilter]
public IActionResult Get()
{
However, for this to work, you need to add media type mapping when configuring MVC:
services.AddMvc(options =>
{
options.ReturnHttpNotAcceptable = true;
options.OutputFormatters.RemoveType<HttpNoContentOutputFormatter>();
options.InputFormatters.Add(new XmlSerializerInputFormatter());
options.OutputFormatters.Add(new XmlSerializerOutputFormatter());
options.FormatterMappings.SetMediaTypeMappingForFormat(
"xml", "application/xml");
});
Now you could make a request with format in URL:
![Image 4](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)