Mik*_*ynn 36 xml asp.net-web-api
如何使用Web API从下面的xml响应中删除命名空间?
<ApiDivisionsResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/GrassrootsHoops.Models.Api.Response">
<Divisions xmlns:d2p1="http://schemas.datacontract.org/2004/07/GrassrootsHoops.Data.Entities">
<d2p1:Page>1</d2p1:Page>
<d2p1:PageSize>10</d2p1:PageSize>
<d2p1:Results xmlns:d3p1="http://schemas.datacontract.org/2004/07/GrassrootsHoops.Models.Api.Response.Divisions"/>
<d2p1:Total>0</d2p1:Total>
</Divisions>
</ApiDivisionsResponse>
Run Code Online (Sandbox Code Playgroud)
Fil*_*p W 41
选项1是切换到使用XmlSerializer中GlobalConfiguration:
config.Formatters.XmlFormatter.UseXmlSerializer = true;
Run Code Online (Sandbox Code Playgroud)
选项2是用你的模型装饰
[DataContract(Namespace="")]
Run Code Online (Sandbox Code Playgroud)
(如果你这样做,你需要用[DataMember]属性装饰成员).
小智 21
如果你愿意用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>
Run Code Online (Sandbox Code Playgroud)
这就是你想要的:
<car>
<doors>
<door>
<color>black</color>
</door>
</doors>
</car>
Run Code Online (Sandbox Code Playgroud)
这是模型:
[XmlRoot("car")]
public class Car
{
[XmlArray("doors"), XmlArrayItem("door")]
public Door[] Doors { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
您需要做的是创建一个自定义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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后要做的是在WebApiContext中添加新的格式化程序.请务必删除(或清除)旧的XmlMediaTypeFormatter
public static class WebApiContext
{
public static void Register(HttpConfiguration config)
{
...
config.Formatters.Clear();
config.Formatters.Add(new CustomNamespaceXmlFormatter{UseXmlSerializer=true});
...
}
}
Run Code Online (Sandbox Code Playgroud)
我喜欢pobed2的回答.但我需要CustomNamespaceXmlFormatter允许我指定一个默认的根名称空间,当该XmlRoot属性丢失时以及它存在且Namespace属性中没有值时使用(也就是说,该属性仅用于设置根元素名称) .所以我创建了一个改进的版本,以防万一它对某人有用:
public class CustomNamespaceXmlFormatter : XmlMediaTypeFormatter
{
private readonly string defaultRootNamespace;
public CustomNamespaceXmlFormatter() : this(string.Empty)
{
}
public CustomNamespaceXmlFormatter(string defaultRootNamespace)
{
this.defaultRootNamespace = defaultRootNamespace;
}
public override Task WriteToStreamAsync(
Type type,
object value,
Stream writeStream,
HttpContent content,
TransportContext transportContext)
{
var xmlRootAttribute = type.GetCustomAttribute<XmlRootAttribute>(true);
if(xmlRootAttribute == null)
xmlRootAttribute = new XmlRootAttribute(type.Name)
{
Namespace = defaultRootNamespace
};
else if(xmlRootAttribute.Namespace == null)
xmlRootAttribute = new XmlRootAttribute(xmlRootAttribute.ElementName)
{
Namespace = defaultRootNamespace
};
var xns = new XmlSerializerNamespaces();
xns.Add(string.Empty, xmlRootAttribute.Namespace);
return Task.Factory.StartNew(() =>
{
var serializer = new XmlSerializer(type, xmlRootAttribute);
serializer.Serialize(writeStream, value, xns);
});
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26966 次 |
| 最近记录: |