Specifying a different serializer per endpoint in Wcf
Posted by Dan Rigsby on April 10th, 2008
I got a question recently on the MSDN forums about being able to specify a different serializer per endpoint in Wcf. For instance, you might have a single service, but some clients want to access it with either XmlSerializer serialized or DataContractSerializer serialized data. If want to know about more about these different serializers, I recommend you read "XmlSerializer vs. DataContractSerializer: Serialization in Wcf".
The problem is that to specify a service is to use the XmlSerializer you need to declare the [XmlSerializerFormat] attribute on the service or the contract. Well since we want to use the same for both endpoints we can’t place it there, so we are left with placing it on the contract. However, when it boils down to it, both endpoints are using the same service and vicariously the same contract right?
Well, it doesn’t have to be so. You could have a contract A derive from contract B, then have the service implement contract A such that everything in both contracts is part of the service. For this example though, contract B will be our standard contract, and contract A will be an interface that just defines the [XmlSerializerFormat] attribute.
Here is a sample service and contract implementation which illustrates this:
[ServiceContract] public interface IMyService { [OperationContract] MyDataType GetData(int id); } [ServiceContract] [XmlSerializerFormat] public interface IMyServiceXmlSerializer : IMyService { } public class MyService : IMyServiceXmlSerializer { public MyDataType GetData(int id) { MyDataType myData = null; // Do logic to get data by id return myData; } } [DataContract] [Serializable] public class MyDataType { }
Here is the app.config for the service. Note the 2 different endpoints are each specifying a different contract and therefore will use different serializers.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="MyNamespace.MyService" behaviorConfiguration="serviceBehavior"> <host> <baseAddresses> <add baseAddress = "http://localhost:8080/MyService" /> </baseAddresses> </host> <endpoint name="dataContractSerializer" address ="" binding="wsHttpBinding" contract="MyNamespace.IMyService"/> <endpoint name="xmlSerializer" address ="xmlSerializer" binding="wsHttpBinding" contract="MyNamespace.IMyServiceXmlSerializer"/> <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> </service> </services> <behaviors> <serviceBehaviors> <behavior name="serviceBehavior"> <serviceMetadata httpGetEnabled="True"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>

















May 7th, 2008 at 10:09 am
Hi Dan,
Ive read this article and also the related XmlSerializer vs. DataContractSerializer and they were both very helpful. There is alot of documentation out there and a lot of hype within it but this is right down to the point. Thanks for that, it was very helpful.
So, as far as I can see there are 3 ways to plugin your own serializers into WCF, 2 which you have outlined in these articles. But the 3rd way I’m not so sure of because like i said there a lot of hype out there in this documentation but from what I gather you can implement your own binding, which knows how to instantiate your binding elements such as serializers or “Encoders”, and then you can configure your endpoint to use that. I’m just having trouble finding documentation on the third. Do you have any useful links or knowledge you can share?
Thanks!
January 26th, 2010 at 10:06 am
Hi Dan,
This looks very interesting and is exactly what i was looing for.
However, I’m trying to host two such service endpoints on IIS 6.0, under the same web site, and can’t get it to work.
Will I have to previde to separate web sites to host individual svc files?
Thanks
Jeremy