By default, when we create a Web API in ASP.NET Core, it is configured to use JSON. The idea is that different clients of different technologies can communicate with our application, sending and receiving information, using the JSON format. However, some API clients may prefer to use another format, such as XML.
We will configure a Web API to support XML. In addition, we will talk about how our clients can request information in both JSON and XML. We’ll see the Accept and Content-Type headers, and we’ll talk about content negotiation.
Prepating the Project
The first thing we will do is create a Web API in ASP.NET Core 3.1. By default we get a controller called WeatherForecastController. In it we can add a Post method which is going to be a method that will receive an instance of WeatherForecast. In the end, the class should look like this:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Extensions.Logging; | |
namespace WebAPIJSONXML.Controllers | |
{ | |
[ApiController] | |
[Route("[controller]")] | |
public class WeatherForecastController : ControllerBase | |
{ | |
private static readonly string[] Summaries = new[] | |
{ | |
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" | |
}; | |
private readonly ILogger<WeatherForecastController> _logger; | |
public WeatherForecastController(ILogger<WeatherForecastController> logger) | |
{ | |
_logger = logger; | |
} | |
[HttpGet] | |
public IEnumerable<WeatherForecast> Get() | |
{ | |
var rng = new Random(); | |
return Enumerable.Range(1, 5).Select(index => new WeatherForecast | |
{ | |
Date = DateTime.Now.AddDays(index), | |
TemperatureC = rng.Next(–20, 55), | |
Summary = Summaries[rng.Next(Summaries.Length)] | |
}) | |
.ToArray(); | |
} | |
[HttpPost] | |
public ActionResult Post(WeatherForecast forecast) | |
{ | |
// Save the weather… | |
return Ok(); | |
} | |
} | |
} |
In order to receive and send data from our Web API in XML format, we need to configure the corresponding services in the Startup class. Luckily for us, this is as simple as invoking a method in the Startup class. The method is called AddXmlDataContractSerializerFormatters and we can use it as follows:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void ConfigureServices(IServiceCollection services) | |
{ | |
services.AddControllers().AddXmlDataContractSerializerFormatters(); | |
} |
Receiving Data in XML – Accept
Now that we have our Web API created and configured, we are ready to receive data from it in JSON format. If we run the Web API and invoke it using Postman, it is likely that you will get the data in JSON format. This is because JSON is the default format used. How can we indicate that we want the data in another format? With the Accept header.
According to MDN:
The Accept request HTTP header advertises which content types, expressed as MIME types, the client is able to understand.
Here the idea is that through this header we can indicate to the Web API the data type that we want to be returned to us, whether it’s JSON (application/json), XML (application/xml), among others. The application/json and application/xml values are examples of media types, or MIME types.
In Postman we can ndicate the media type we want to be returned to us, using the Headers tab:
With this, the Web API will return the response in JSON format:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[ | |
{ | |
"date": "2020-01-21T14:53:53.35732-04:00", | |
"temperatureC": 21, | |
"temperatureF": 69, | |
"summary": "Scorching" | |
}, | |
{ | |
"date": "2020-01-22T14:53:53.3573213-04:00", | |
"temperatureC": 1, | |
"temperatureF": 33, | |
"summary": "Freezing" | |
} | |
… | |
] |
However, if you change the Accept value to “application/xml”, then we will get an answer in XML format:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ArrayOfWeatherForecast xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/WebAPIJSONXML"> | |
<WeatherForecast> | |
<Date>2020-01-21T14:38:11.9403235-04:00</Date> | |
<Summary>Mild</Summary> | |
<TemperatureC>52</TemperatureC> | |
</WeatherForecast> | |
<WeatherForecast> | |
<Date>2020-01-22T14:38:11.9403337-04:00</Date> | |
<Summary>Hot</Summary> | |
<TemperatureC>27</TemperatureC> | |
</WeatherForecast> | |
… | |
</ArrayOfWeatherForecast> |
An indispensable part of the previous XML structure is “xmlns=” http://schemas.datacontract.org/2004/07/WebAPIJSONXML”, which is the way to indicate the structure of the XML.
Content Negotiation
We saw two examples, one where we requested a resource with JSON representation and another in XML. However, what if we want to tell the Web API a list of formats which we can accept? We can do this by indicating various media types.
For example:
Accept: application/zip, application/xml
In the previous case, we are requesting two types of media: application/zip and application/xml. We know that our application does not serve application/zip, therefore, our application uses the next value. The Web API will use the first type of content that it finds it can serve. We call this content negotiation.
Content-Type
In addition to our Web API being able to send data in XML format, we want it to receive information in this format. For that we must use the Content-Type header to indicate the media type of the resource to be sent during a POST method:
Then, in the Body tab we place an XML structure (taken from the response obtained from the Web API):
Note that I am including the xmlns attribute to indicate the XML namespace. Without this attribute, you will get an error.
If we press Send, we will get an Ok from the Web API, indicating that we could effectively send the XML.
We can also send a JSON to our Web API if we wish.
Summary
- We can easily configure our Web API to provide and receive data in XML format
- The Accept header is used to indicate the media type we accept as a response (this can be JSON, XML, among others)
- Content negotiation refers to the process of determining the best content format for a given request
- The Content-Type header is used to indicate the media type of the resource.
Regards!