web-dev-qa-db-ja.com

Web APIメソッドからXMLデータを返す方法は?

Xmlデータを返すはずのWeb Apiメソッドがありますが、それは文字列を返します。

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

            return healthCheckReport.ToXml();
        }
    }

それは返します:

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

そして私はこのマッピングを追加しました:

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

Xmlビットのみを返すようにする方法:

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

MVCだけを使用していた場合、以下を使用できますが、Web APIは「コンテンツ」をサポートしていません。

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

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

また、以下のコードをWebApiConfigクラスに追加しました。

 config.Formatters.Remove(config.Formatters.JsonFormatter);
 config.Formatters.XmlFormatter.UseXmlSerializer = true;
20
The Light

最速の方法はこれです、

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

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

ただし、HttpContentから派生してXmlDocumentまたはXDocumentを直接サポートする新しいXmlContentクラスを作成することも非常に簡単です。例えば.

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

xmlDocumentを受け入れることを除いて、StreamContentまたはStringContentを使用するのと同じように使用できます。

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

       return new HttpResponseMessage() {
           RequestMessage = Request,
           Content = new XmlContent(healthCheckReport.ToXmlDocument()) };
    }
}
42
Darrel Miller