网络 api - xml 前缀
Web api - xml prefixes
美好的一天,通过使用网络 api,我需要获得以下 xml 响应(包含所有前缀):
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ai="www.something.org">
<ai:name>Ann</name>
</test>
这是 class:
[XmlRoot(ElementName = "test")]
public class Test
{
[XmlAttribute(AttributeName = "ai")]
public const string Ai = "www.something.org";
[XmlElement(ElementName = "name",Namespace = Ai)]
public string Name { get; set; }
public Test(string name)
{
Name = name;
}
public Test() { }
}
问题是,如果你单独使用 xmlSerializer,你可以使用
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("ai", "www.something.org");
但这里的序列化是由网络 api 请求本身进行的:
[HttpGet]
[Route("test")]
public Test Testing()
{
return new Test("Ann");
}
我得到的是没有 ai
属性,也没有命名空间前缀。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name xmlns="www.something.org">
Ann
</name>
编辑。 如果我覆盖 XmlMediaTypeFormatter
,我会得到正确的 xml 响应:
public class CustomXmlFormatter : XmlMediaTypeFormatter
{
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
TransportContext transportContext)
{
var serializer = new XmlSerializer(type);
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("ai", "www.something.org");
return Task.Factory.StartNew(() =>
{
using (var streamWriter = new StreamWriter(writeStream, Encoding.UTF8))
{
serializer.Serialize(streamWriter, value,ns);
}
});
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
}
但是 如果我有 2 个请求,每个请求都有不同的命名空间怎么办 - 但此格式化程序将始终显示它们。有什么办法可以删除未使用的名称空间?
如果您像这样定义自定义 xml 格式化程序:
public class CustomXmlFormatter : XmlMediaTypeFormatter
{
public XmlSerializerNamespaces Namespaces { get; }
public CustomXmlFormatter()
{
Namespaces = new XmlSerializerNamespaces();
}
public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext)
{
var serializer = new XmlSerializer(type);
var xmlWriter = new XmlTextWriter(writeStream, Encoding.UTF8)
{
Namespaces = true
};
serializer.Serialize(xmlWriter, value, Namespaces);
return Task.FromResult(true);
}
}
然后您可以创建一个 IControllerConfiguration
使用此格式化程序并添加您的命名空间:
public class MyControllerConfig : Attribute, IControllerConfiguration
{
private readonly string _prefix;
private readonly string _ns;
public MyControllerConfig(string prefix, string ns)
{
_prefix = prefix;
_ns = ns;
}
public void Initialize(HttpControllerSettings controllerSettings,
HttpControllerDescriptor controllerDescriptor)
{
var formatter = new CustomXmlFormatter { UseXmlSerializer = true };
formatter.Namespaces.Add(_prefix, _ns);
controllerSettings.Formatters.Clear();
controllerSettings.Formatters.Add(formatter);
}
}
然后在你的控制器上使用这个:
[MyControllerConfig("ai", Ns.Ai)]
public class MyController : ApiController
{
[HttpGet]
[Route("test")]
public IHttpActionResult Testing()
{
return Ok(new Test("Ann"));
}
}
public class Ns
{
public const string Ai = "www.something.org";
}
[XmlRoot(ElementName = "test")]
public class Test
{
[XmlElement(ElementName = "name", Namespace = Ns.Ai)]
public string Name { get; set; }
public Test(string name)
{
Name = name;
}
public Test() { }
}
美好的一天,通过使用网络 api,我需要获得以下 xml 响应(包含所有前缀):
<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ai="www.something.org">
<ai:name>Ann</name>
</test>
这是 class:
[XmlRoot(ElementName = "test")]
public class Test
{
[XmlAttribute(AttributeName = "ai")]
public const string Ai = "www.something.org";
[XmlElement(ElementName = "name",Namespace = Ai)]
public string Name { get; set; }
public Test(string name)
{
Name = name;
}
public Test() { }
}
问题是,如果你单独使用 xmlSerializer,你可以使用
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("ai", "www.something.org");
但这里的序列化是由网络 api 请求本身进行的:
[HttpGet]
[Route("test")]
public Test Testing()
{
return new Test("Ann");
}
我得到的是没有 ai
属性,也没有命名空间前缀。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<name xmlns="www.something.org">
Ann
</name>
编辑。 如果我覆盖 XmlMediaTypeFormatter
,我会得到正确的 xml 响应:
public class CustomXmlFormatter : XmlMediaTypeFormatter
{
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
TransportContext transportContext)
{
var serializer = new XmlSerializer(type);
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("ai", "www.something.org");
return Task.Factory.StartNew(() =>
{
using (var streamWriter = new StreamWriter(writeStream, Encoding.UTF8))
{
serializer.Serialize(streamWriter, value,ns);
}
});
return base.WriteToStreamAsync(type, value, writeStream, content, transportContext);
}
}
但是 如果我有 2 个请求,每个请求都有不同的命名空间怎么办 - 但此格式化程序将始终显示它们。有什么办法可以删除未使用的名称空间?
如果您像这样定义自定义 xml 格式化程序:
public class CustomXmlFormatter : XmlMediaTypeFormatter
{
public XmlSerializerNamespaces Namespaces { get; }
public CustomXmlFormatter()
{
Namespaces = new XmlSerializerNamespaces();
}
public override Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext)
{
var serializer = new XmlSerializer(type);
var xmlWriter = new XmlTextWriter(writeStream, Encoding.UTF8)
{
Namespaces = true
};
serializer.Serialize(xmlWriter, value, Namespaces);
return Task.FromResult(true);
}
}
然后您可以创建一个 IControllerConfiguration
使用此格式化程序并添加您的命名空间:
public class MyControllerConfig : Attribute, IControllerConfiguration
{
private readonly string _prefix;
private readonly string _ns;
public MyControllerConfig(string prefix, string ns)
{
_prefix = prefix;
_ns = ns;
}
public void Initialize(HttpControllerSettings controllerSettings,
HttpControllerDescriptor controllerDescriptor)
{
var formatter = new CustomXmlFormatter { UseXmlSerializer = true };
formatter.Namespaces.Add(_prefix, _ns);
controllerSettings.Formatters.Clear();
controllerSettings.Formatters.Add(formatter);
}
}
然后在你的控制器上使用这个:
[MyControllerConfig("ai", Ns.Ai)]
public class MyController : ApiController
{
[HttpGet]
[Route("test")]
public IHttpActionResult Testing()
{
return Ok(new Test("Ann"));
}
}
public class Ns
{
public const string Ai = "www.something.org";
}
[XmlRoot(ElementName = "test")]
public class Test
{
[XmlElement(ElementName = "name", Namespace = Ns.Ai)]
public string Name { get; set; }
public Test(string name)
{
Name = name;
}
public Test() { }
}