ASP.NET WEBApi 輸出指定的XML格式

  • 845
  • 0

ASP.NET WEBApi XML

最近有一個需求,指定要用WebApi輸出XML,而且不能有任何的namespace跟 attribute,連XML宣告都不要。

一般輸出成XML檔時,預設都會有XML宣告跟namespace,找了好久才搞定,在此紀錄一下。

1.自訂一個XMLFormatter,繼承原本的XMLFormatter,並改寫WriteToStreamAsync方法。

2.在WebApiConfig.cs中,移除所有的formatter後,再加進自訂的XMLFormatter。如果有json輸出的需求,怎麼辦?放大絕啦!通通移除掉,再把jsonFormatter加回去

 

原始碼參考如下:

1.WebApiConfig.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using Microsoft.Owin.Security.OAuth;
using Newtonsoft.Json.Serialization;

namespace webAPI
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 設定和服務
            // 將 Web API 設定成僅使用 bearer 權杖驗證。
            config.SuppressDefaultHostAuthentication();
            config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
            config.Formatters.Clear();
            var custom = new Models.CustomNamespaceXmlFormatter();
            config.Formatters.Add(custom);
        }
    }
}

2.CustomNamespaceXmlFormatter

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Xml.Serialization;

namespace webAPI.Models
{
    public class CustomNamespaceXmlFormatter : XmlMediaTypeFormatter
    {

        public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
                                                TransportContext transportContext)
        {


            try
            {

                var xns = new XmlSerializerNamespaces();

                foreach (var attribute in type.GetCustomAttributes(true))
                {
                    var xmlRootAttribute = attribute as XmlRootAttribute;
                    if (xmlRootAttribute != null)
                    {
                        xns.Add(string.Empty, xmlRootAttribute.Namespace); //加進空的namespace,取代原本預設的namespace
                    }
                }

                if (xns.Count == 0)
                {
                    xns.Add(string.Empty, string.Empty);
                }

                var task = Task.Factory.StartNew(() =>
                {
                    //建立新的XmlSerializer跟XmlWriter,並設定忽略宣告內容及指定縮排方式
                    var serializer = new XmlSerializer(type);
                    XmlWriter writer = XmlWriter.Create(writeStream, new XmlWriterSettings { OmitXmlDeclaration = true, Indent = true });
                    serializer.Serialize(writer, value, xns);
                });

                return task;
            }
            catch (Exception)
            {
                return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
            }
        }
    }

}

打完收工,看一下輸出的結果吧,喔耶,good job!!!