21

I have a Web Api method which should return an xml data but it returns string:

 public class HealthCheckController : ApiController
    {       
        [HttpGet]
        public string Index()
        {
            var healthCheckReport = new HealthCheckReport();

            return healthCheckReport.ToXml();
        }
    }

It returns:

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
<myroot><mynode></mynode></myroot>
</string>

and I have added this mapping:

 config.Routes.MapHttpRoute(
              name: "HealthCheck",
              routeTemplate: "healthcheck",
              defaults: new
              {
                  controller = "HealthCheck",
                  action = "Index"
              });

How to make it return just the xml bits:

<myroot><mynode></mynode></myroot>

If I was using just MVC, I could be using the below but Web API doesn't support "Content":

 [HttpGet]
        public ActionResult Index()
        {
            var healthCheckReport = new HealthCheckReport();

            return Content(healthCheckReport.ToXml(), "text/xml");
        }

I have also added the below codes to the WebApiConfig class:

 config.Formatters.Remove(config.Formatters.JsonFormatter);
 config.Formatters.XmlFormatter.UseXmlSerializer = true;
1
  • 1
    Can you just return the HealthCheckReport instance, and let the XML formatter do the serialization? Right now, you are serializing to XML in your controller and then passing that string to the XML formatter. Then the XML formatter serializes the string to XML. Commented Mar 14, 2013 at 17:29

1 Answer 1

45

The quickest way is this,

 public class HealthCheckController : ApiController
 {       
     [HttpGet]
     public HttpResponseMessage Index()
     {
         var healthCheckReport = new HealthCheckReport();

         return new HttpResponseMessage() {Content = new StringContent( healthCheckReport.ToXml(), Encoding.UTF8, "application/xml" )};
     }
 }

but it is also very easy to build a new XmlContent class that derives from HttpContent to support XmlDocument or XDocument directly. e.g.

public class XmlContent : HttpContent
{
    private readonly MemoryStream _Stream = new MemoryStream();

    public XmlContent(XmlDocument document) {
        document.Save(_Stream);
            _Stream.Position = 0;
        Headers.ContentType = new MediaTypeHeaderValue("application/xml");
    }

    protected override Task SerializeToStreamAsync(Stream stream, System.Net.TransportContext context) {

        _Stream.CopyTo(stream);

        var tcs = new TaskCompletionSource<object>();
        tcs.SetResult(null);
        return tcs.Task;
    }

    protected override bool TryComputeLength(out long length) {
        length = _Stream.Length;
        return true;
    }
}

and you can use it just like you would use StreamContent or StringContent, except that it accepts a XmlDocument,

public class HealthCheckController : ApiController
{       
    [HttpGet]
    public HttpResponseMessage Index()
    {
       var healthCheckReport = new HealthCheckReport();

       return new HttpResponseMessage() {
           RequestMessage = Request,
           Content = new XmlContent(healthCheckReport.ToXmlDocument()) };
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

How is the XmlContent class used? Does it have to registered somewhere?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.