WebAPI to Return XML

I’m wanting my WEB API method to return an XML object back to the calling application. Currently it’s just returning the XML as a string object. Is this a no no? If so how do you tell the webapi get method that it’s returning an object of type XML?

Thanks

Edit: An example of the Get method:

[AcceptVerbs("GET")]
public HttpResponseMessage Get(int tenantID, string dataType, string ActionName)
{
   List<string> SQLResult = MyWebSite_DataProvidor.DB.spReturnXMLData
            ("SELECT * FROM vwContactListing FOR XML AUTO, ELEMENTS").ToList();
   string AllResults = "";
   for (int i = 0; i < SQLResult.Count - 1; i++)
   {
       AllResults += SQLResult[i];
   }
    string sSyncData = "<?xml version="1.0"?> " + AllResults;
    HttpResponseMessage response = new HttpResponseMessage();
    response.Content = new StringContent(sSyncData);
    return response;          
}

Its a bit hacky because im still at the prototyping stage. Will refactor when i can prove its doable.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

If you don’t want the controller to decide the return object type, you should set your method return type as System.Net.Http.HttpResponseMessage and use the below code to return the XML.

public HttpResponseMessage Authenticate()
{
  //process the request 
  .........

  string XML="<note><body>Message content</body></note>";
  return new HttpResponseMessage() 
  { 
    Content = new StringContent(XML, Encoding.UTF8, "application/xml") 
  };
}

This is the quickest way to always return XML from Web API.

Method 2

If you return a serializable object, WebAPI will automatically send JSON or XML based on the Accept header that your client sends.

If you return a string, you’ll get a string.

Method 3

Here’s another way to be compatible with an IHttpActionResult return type. In this case I am asking it to use the XML Serializer(optional) instead of Data Contract serializer, I’m using return ResponseMessage( so that I get a return compatible with IHttpActionResult:

return ResponseMessage(new HttpResponseMessage(HttpStatusCode.OK)
       {
           Content = new ObjectContent<SomeType>(objectToSerialize, 
              new System.Net.Http.Formatting.XmlMediaTypeFormatter { 
                  UseXmlSerializer = true 
              })
       });

Method 4

You should simply return your object, and shouldn’t be concerned about whether its XML or JSON. It is the client responsibility to request JSON or XML from the web api. For example, If you make a call using Internet explorer then the default format requested will be Json and the Web API will return Json. But if you make the request through google chrome, the default request format is XML and you will get XML back.

If you make a request using Fiddler then you can specify the Accept header to be either Json or XML.

Accept: application/xml

You may wanna see this article: Content Negotiation in ASP.NET MVC4 Web API Beta – Part 1

EDIT: based on your edited question with code:

Simple return list of string, instead of converting it to XML. try it using Fiddler.

public List<string> Get(int tenantID, string dataType, string ActionName)
    {
       List<string> SQLResult = MyWebSite_DataProvidor.DB.spReturnXMLData("SELECT * FROM vwContactListing FOR XML AUTO, ELEMENTS").ToList();
       return SQLResult;
     }

For example if your list is like:

List<string> list = new List<string>();
list.Add("Test1");
list.Add("Test2");
list.Add("Test3");
return list;

and you specify Accept: application/xml the output will be:

<ArrayOfstring xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
  <string>Test1</string>
  <string>Test2</string>
  <string>Test3</string>
</ArrayOfstring>

and if you specify ‘Accept: application/json’ in the request then the output will be:

[
  "Test1",
  "Test2",
  "Test3"
]

So let the client request the content type, instead of you sending the customized xml.

Method 5

In my project with netcore 2.2 I use this code:

[HttpGet]
[Route( "something" )]
public IActionResult GetSomething()
{
    string payload = "Something";

    OkObjectResult result = Ok( payload );

    // currently result.Formatters is empty but we'd like to ensure it will be so in the future
    result.Formatters.Clear();

    // force response as xml
    result.Formatters.Add( new Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter() );

    return result;
}

It forces only one action within a controller to return a xml without effect to other actions. Also this code doesn’t contain neither HttpResponseMessage or StringContent or ObjectContent which are disposable objects and hence should be handled appropriately (it is especially a problem if you use any of code analyzers that reminds you about it).

Going further you could use a handy extension like this:

public static class ObjectResultExtensions
{
    public static T ForceResultAsXml<T>( this T result )
        where T : ObjectResult
    {
        result.Formatters.Clear();
        result.Formatters.Add( new Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter() );

        return result;
    }
}

And your code will become like this:

[HttpGet]
[Route( "something" )]
public IActionResult GetSomething()
{
    string payload = "Something";

    return Ok( payload ).ForceResultAsXml();
}

In addition, this solution looks like an explicit and clean way to force return as xml and it is easy to add to your existent code.

P.S. I used fully-qualified name Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter just to avoid ambiguity.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x