Frage

We're trying to remove all namespacing from our XML API responses. We're using a custom BufferedMediaTypeFormatter that looks like:

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);
        }
    }
}

As we understand it (from answers like this), that namespaces.Add(string.Empty, string.Empty); should remove all namespaces from any serialized XML. In unit tests, that's exactly what it does:

[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>'
                );
            }
        }
}

However in the deployed application, it adds default namespaces!

GET /Section/21

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

Maybe it's something configured in our Global.asax?:

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

Any help getting rid of those would be greatly appreciated.

War es hilfreich?

Lösung

Make sure to add the supported media types:

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

Also I see that you want to still keep the default xml formatter...so you want this custom formatter to only apply to SectionResponse type and for all other types the default xml formatter should apply...is it?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top