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!!!