【问题标题】:Custom XmlSerializer only adds namespaces in WebApi自定义 XmlSerializer 只在 WebApi 中添加命名空间
【发布时间】:2014-01-27 18:36:24
【问题描述】:

我们正在尝试从我们的 XML API 响应中删除所有命名空间。我们正在使用一个自定义的BufferedMediaTypeFormatter,它看起来像:

namespace HeyWorld.MediaTypeFormatters
{
    public class SectionMediaTypeFormatter : BufferedMediaTypeFormatter
    {
        public override bool CanReadType(Type type)
        {
            return typeof(SectionResponse) == type;
        }

        public override bool CanWriteType(Type type)
        {
            return typeof(SectionResponse) == type;
        }

        public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
        {
            var xmlWriterSettings = new XmlWriterSettings { OmitXmlDeclaration = true, Encoding = Encoding.UTF8 };

            using (XmlWriter writer = XmlWriter.Create(writeStream, xmlWriterSettings))
            {
                var namespaces = new XmlSerializerNamespaces();
                namespaces.Add(string.Empty, string.Empty);
                var serializer = new XmlSerializer(type);
                serializer.Serialize(writer, value, namespaces);
            }
        }

        public override object ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
        {
            var serializer = new XmlSerializer(type);
            return serializer.Deserialize(readStream);
        }
    }
}

据我们了解(来自this 之类的答案),namespaces.Add(string.Empty, string.Empty); 应该从任何序列化的 XML 中删除所有命名空间。在单元测试中,这正是它的作用:

[Test]
public void ShouldntDoNamespaces(){
     var sectionResponse = new SectionResponse("yes!");
     var sectionMediaTypeFormatter = new SectionMediaTypeFormatter();

     using (var memoryStream = new MemoryStream())
     {
         sectionMediaTypeFormatter.WriteToStream(typeof(T), sectionResponse, memoryStream, null);

            using (var reader = new StreamReader(memoryStream))
            {
                memoryStream.Position = 0;
                Assert.That(reader.ReadToEnd(), Is.EqualTo(
                    '<Section attribute="yes!"></Section>'
                );
            }
        }
}

但是在部署的应用程序中,它添加了默认命名空间!

GET /Section/21

<Section 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    attribute="yes!"></Section>

也许它是在我们的 Global.asax 中配置的?:

    GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;
    GlobalConfiguration.Configuration.Formatters.Insert(0, new SectionMediaTypeFormatter());

任何帮助摆脱这些将不胜感激。

【问题讨论】:

    标签: c# xml asp.net-web-api xml-serialization xmlserializer


    【解决方案1】:

    确保添加支持的媒体类型:

    public class SectionMediaTypeFormatter : BufferedMediaTypeFormatter
    {
        public SectionMediaTypeFormatter()
        {
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/xml"));
            this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/xml"));
        }
    

    我还看到您仍然希望保留默认的 xml 格式化程序...所以您希望此自定义格式化程序仅适用于 SectionResponse 类型,而对于所有其他类型,默认的 xml 格式化程序应该适用...是吗?

    【讨论】:

    • 是的,我们正在尝试慢慢解决问题。但媒体类型很到位。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多