自定义XmlSerializer仅在WebApi中添加名称空间

时间:2014-01-27 18:36:24

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

我们正在尝试从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());

任何帮助摆脱这些将非常感激。

1 个答案:

答案 0 :(得分:4)

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

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

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