Muhammad Adeel Zahid
Muhammad Adeel Zahid

Reputation: 17784

Using different XML serializer for reading and writing objects: Asp.net web-api

I want to use DataContractSerializer to serialize the responses and XmlSerializer to deserialize the xml in incoming requests. Is it possible? I know I can use different serializers for different types but I want different serializers for read and write.

Upvotes: 1

Views: 382

Answers (1)

Rick Strahl
Rick Strahl

Reputation: 17651

That seems like a really odd request, but yes it's possible. You can create a custom MediaType formatter like this:

public class DcsXsFormatter : MediaTypeFormatter
{
    public DataContractXmlFormatter()
    {
        SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/xml"));
        SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/xml"));
    }

    public override bool CanWriteType(Type type)
    {
        return true;
    }

    public override bool CanReadType(Type type)
    {
        return true;
    }

    public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, 
                                                     HttpContent content, 
                                                     IFormatterLogger formatterLogger)
    {
        var task = Task<object>.Factory.StartNew(() =>
            {
                var ser = new XmlSerializer(type);
                return ser.Deserialize(readStream);
            });

        return task;
    }

    public override Task WriteToStreamAsync(Type type, object value, 
                                    Stream writeStream, 
                                    HttpContent content, 
                                    TransportContext transportContext)
    {            
        var task = Task.Factory.StartNew( () =>
            {                    
                var ser = new DataContractSerializer(type);
                ser.WriteObject(writeStream,value);                    
                writeStream.Flush();
            });

        return task;
    }
}

To hook it up in global.asax:

// remove existing XmlFormatter config.Formatters.Remove(config.Formatters.XmlFormatter);

// Hook in your custom XmlFormatter
config.Formatters.Insert(0, new  DcsXsFormatter());

But why would you want to do this?

Upvotes: 3

Related Questions