Skip to main content
 首页 » 编程设计

c#之自定义 XmlSerializer 只在 WebApi 中添加命名空间

2024年02月13日2752php

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

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

请您参考如下方法:

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

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

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