如果你愿意用 XmlRoot 来装饰你的模型,这是一个很好的方法。假设你有一辆带门的汽车。默认的 WebApi 配置将返回如下内容:
<car
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<doors>
<door>
<color>black</color>
</door>
</doors>
</car>
这就是你想要的:
<car>
<doors>
<door>
<color>black</color>
</door>
</doors>
</car>
这是模型:
[XmlRoot("car")]
public class Car
{
[XmlArray("doors"), XmlArrayItem("door")]
public Door[] Doors { get; set; }
}
您需要做的是创建一个自定义 XmlFormatter,如果 XmlRoot 属性中没有定义命名空间,它将有一个空的命名空间。出于某种原因,默认格式化程序总是添加两个默认命名空间。
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);
}
}
if (xns.Count == 0)
{
xns.Add(string.Empty, string.Empty);
}
var task = Task.Factory.StartNew(() =>
{
var serializer = new XmlSerializer(type);
serializer.Serialize(writeStream, value, xns);
});
return task;
}
catch (Exception)
{
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
}
}
最后要做的是在 WebApiContext 中添加新的格式化程序。请务必删除(或清除)旧的 XmlMediaTypeFormatter
public static class WebApiContext
{
public static void Register(HttpConfiguration config)
{
...
config.Formatters.Clear();
config.Formatters.Add(new CustomNamespaceXmlFormatter{UseXmlSerializer=true});
...
}
}