WebAPI to Return XML

asp.netasp.net Mvcasp.net Web-Api

asp.net Problem Overview


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.

asp.net Solutions


Solution 1 - asp.net

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.

Solution 2 - asp.net

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.

Solution 3 - asp.net

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 
              })
       });

Solution 4 - asp.net

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.

Solution 5 - asp.net

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMattView Question on Stackoverflow
Solution 1 - asp.netArkadas KilicView Answer on Stackoverflow
Solution 2 - asp.netAdam BaxterView Answer on Stackoverflow
Solution 3 - asp.netAaronLSView Answer on Stackoverflow
Solution 4 - asp.netHabibView Answer on Stackoverflow
Solution 5 - asp.netAlex IlinView Answer on Stackoverflow