I need my HttpController to receive raw XML and pass it on to legacy code. I try this:
[HttpPost]
[Route("/xml")]
public string Post([FromForm] XDocument xml)
{
return xml.ToString();
}
However, the xml document seems to be always empty, e.g.,
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i
HTTP/1.1 200 OK
Date: Fri, 26 Feb 2021 10:19:23 GMT
Content-Type: text/plain; charset=utf-8
Server: Kestrel
Content-Length: 0
$
How do I read raw XML from the request body and obtain a valid XDocument?
First, ASP.NET Core does not support XML serialization/deserialization by default. You must explicitly enable that:
services.AddControllersWithViews().AddXmlSerializerFormatters();
Then, to send raw XML format data to API method, the request's content-Type should be application/xml, and we will receive the xml content from the request body, so we should use the [FromBody] attribute, and we should use the XElement to receive the xml content. Please refer to the following sample:
Create a Values API with the following code:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// POST api/<ValuesController>
[HttpPost]
[Route("/xml")]
public string Post([FromBody]XElement xml)
{
return "Hello" + xml.ToString();
}
Then using Postman to call this API:

Besides, you could also according to the XML elements to create model, then using model class to receive the xml content. Check the following sample:
The XML content as below:
<?xml version="1.0" encoding="UTF-8"?>
<UserViewModel>
<Id>1</Id>
<Name>aa</Name>
</UserViewModel>
Create a UserViewModel
public class UserViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Then, in the API controller, using the following method to receive data:
[HttpPost]
public string Post([FromBody]UserViewModel user)
{
return "Hello" + user.Name.ToString();
}
Using Postman to check it:

The [FromForm] attribute will receive the Form data in the request body. Form data as the name suggests is used to send the data that you are wrapping inside the form like the details you enter when you fill a form. These details are sent by writing them as KEY-VALUE pairs where the key is the "name" of the entry you are sending and value is it’s value. More detail information, you could refer this thread.
Since you are using curl to send request, try to use -H or --header to set the request header, like this:
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i -H "Content-Type: text/xml"
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i -H "Content-Type:application/xml"
or
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i --header "Content-Type: text/xml"
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i --header "Content-Type:application/xml"
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