Share via


How to return Xml response (with Xml declaration) from WebAPI?

Question

Friday, March 9, 2018 1:56 PM

I have managed to put two XDocuments together in my code. When I call my API (which returns IHttpActionResult) with PostMan, I get the following result:

<ContentNode1>

*    <tag1>data1</tag1>*

*    <tag2>data2</tag2>*

*    <tag3>data3</tag3>*

*    <ContentNode2>*

*        <tag4>data4</tag4>*

*        <tag5>data5</tag5>*

*    </ContentNode2>*

</ContentNode1>

However, the end result should be this instead:

<?xml version='1.0' encoding='utf-8'?>

<ContentNode1>

*    <tag1>data1</tag1>*

*    <tag2>data2</tag2>*

*    <tag3>data3</tag3>*

*    <ContentNode2>*

*        <tag4>data4</tag4>*

*        <tag5>data5</tag5>*

*    </ContentNode2>*

</ContentNode1>

Merging two XDocuments happens currently as follows:

var xml1 = XDocument.Parse(xmlSource1);

var xml2 = XDocument.Parse(xmlSource2); 

xml1.Descendants("contentnode1").LastOrDefault().Add(xml2.Descendants("contentnode2"));

xml1.Declaration = new XDeclaration("1.0", "UTF-8", "yes"); 

// Storing combined result in a property

controller.MergedXML = xml1.Declaration.ToString() + xml1.ToString(); 

Finally, when I return the whole XML, it goes through these lines: 

var requestResult = XDocument.Parse(controller.MergedXML); 

var returnValue = Content(HttpStatusCode.OK, requestResult); 

return returnValue; 

These previous three lines of code give me the following error: 

"Type 'System.Xml.Linq.XDeclaration' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.  If the type is a collection, consider marking it with the CollectionDataContractAttribute.  See the Microsoft .NET Framework documentation for other supported types." 

When I look at the controller.MergedXML property, it shows me this XML in PostMan:

<?xml version=\1.0\ encoding=\UTF-8\ standalone=\yes\?><ContentNode1>\r\n  <tag1>data1</tag1>\r\n  <tag2>data2</tag2>\r\n  <tag3>data3</tag3>\r\n  <ContentNode2>\r\n    <tag4>data4</tag4>\r\n    <tag5>data5</tag5>\r\n  </ContentNode2>\r\n</ContentNode1>

So the XML declaration is there. Yet, it finally either disappears or I get an error because of the declaration.

If I assign a value to requestResult like this:

var requestResult  = controller.MergedXML;

I get this kind of result (in PostMan):

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/"><?xml version="1.0" encoding="UTF-8" standalone="yes"?><ContentNode1>

*  <tag1>data1</tag1>*

*  <tag2>data2</tag2>*

* * <tag3>data3</tag3>

*  <ContentNode2>*

*    <tag4>data4f</tag4>*

*    <tag5>data5</tag5>*

*  </ContentNode2>*

</ContentNode1></string>

Finally, if I use the following line, I get the combined XML, but without the XML declaration (see the example at the top of this post):

var requestResult = XElement.Parse(conv.ConversationAndTag);

So the goal is to have the XML to show up with the declaration, when calling WebAPI (IHttpActionResult as return type) by using PostMan.

I’m new to XML and WebAPI, so perhaps this is very simple thing to do .

All replies (2)

Friday, March 9, 2018 3:40 PM

You need to rethink the approach.  Return a complex type from Web API as the .NET framework will serialize the XML automatically.  That means you'll need to craft an complex type to hold the results of the two xml data sources.

The problem with the current code is you are trying to return an Xml Type as the error suggests.  


Friday, March 9, 2018 4:16 PM

the point of webapi is serialize incoming and outgoing objects via the requested formatters. if you want to control the out, then you just create the response yourself. see:

/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/action-results