Custom processor for text/xml and application/xml

Topics: Web Api
Mar 3, 2011 at 9:17 PM

Hi all,

I am having problem with serialization with the default XmlProcessor as it uses the XmlSerializer (mainly around private setters).

I have created a custom processor for text/xml and application/xml that uses DataContractSerializer. But the new processor does not work, because by default there is already a processor for the two types already registered.

Is there anyway I can register the new processor?

Thanks

Mar 3, 2011 at 9:37 PM

Try creating a custom HttpHostConfiguration and implement IProcessorProvider, then clear the MediaTypeProcessors and add your own.

HttpHostConfiguration, IProcessorProvider

public void RegisterResponseProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
{
        processors.ClearMediaTypeProcessors();
        processors.Add(new CustomProcessor(operation, mode));
}

Mar 4, 2011 at 4:57 PM

Thanks for the response.

Clearing all media types caused additional issues with JSON processors.

Here is the final code I ended up with:

public void RegisterResponseProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
{
     processors.Remove(new XmlProcessor(operation, mode));
     processors.Add(new DataContractProcessor(operation, mode));
}


Coordinator
Mar 4, 2011 at 5:14 PM

Hi srazzaq

Does that remove work? Instead I would use a linq query to find the processor OfType<XmlProcessor> and remove it. Also we process in order, so if you just insert yours first, it should also work. The processors are a list, so you can insert.

Glenn

Mar 4, 2011 at 6:44 PM

Hy srazzaq,

Doing a linq query would probably be better like Glenn suggests.  However I also had a problem with clearing / adding processors.  Calling "SetProcessorProvider" seemed to help.

 

public class RestHttpConfiguration : HttpHostConfiguration, IProcessorProvider, IInstanceFactory
{
    private readonly CompositionContainer _Container;
    
    public RestHttpConfiguration(CompositionContainer container)
    {
        if (container != null)
        {
            _Container = container;
        }
        
        SetProcessorProvider(this);
    }

    public void RegisterRequestProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
    {
        processors.Add(new JsonNetProcessor(operation, mode));
        processors.Add(new XmlDataContractProcessor(operation, mode));
    }

    public void RegisterResponseProcessorsForOperation(HttpOperationDescription operation, IList<Processor> processors, MediaTypeProcessorMode mode)
    {
        processors.ClearMediaTypeProcessors();
        processors.Add(new JsonNetProcessor(operation, mode));
        processors.Add(new XmlDataContractProcessor(operation, mode));
    }
}
Mar 8, 2011 at 10:38 PM

I switched to Linq Query to remove the processor. It was working before, but I agree this is better.

Thank you for your help.

Out of curiosity, is there a reason XmlSerializer is being used instead of DataContractSerializer? It seems like it will cause issues for people trying to convert existing WCF services.

May 14, 2011 at 3:25 PM

Any chance of including a DataContractSerializer based formatter out of the box? The default XmlSerializer implementation is pretty like to throw exceptions for normal use entities.

Coordinator
May 14, 2011 at 8:05 PM

We do support DataContractSerializer but it's a bit of work to turn it on. DCS was really not a priority as we optimized or xml serializer.

However: I've gone and pushed a few extension methods in webapicontrib which will help you. I've also included a sample which shows how to use the methods which you can find here

Hopefully we can make this a little easier.

Coordinator
May 15, 2011 at 3:56 AM

Just blogged on the new methods: http://blogs.msdn.com/b/endpoint/archive/2011/05/15/using-datacontracts-with-wcf-web-api.aspx