Custom Serialization with WCF services


  • 1) How do I override the default serialization for a WCF Service?
    ie: Given the following: ServiceResponse SomeMethodCall(ServiceRequest)
     - how do I override the serialization of ServiceResponse to be custom (for example if I just wanted to
    serialize ServiceResponse to a comma delimited string over the wire)

    2) How can I override the deserialization of the proxy-generated ServiceResponse on the client-side? (Silverlight client)

    I've run quite a bit of reading, but am getting lost in the sea of DataContractSerializers / IXMLSerialize etc etc.

    3) Is it possible to provide a serialization switch in the method call, and then use the framework serialization, or the custom serialization depending on the switch.

    With our in-house client, we would like to minimise comms across the wire with custom serialization, but to 3rd party consumers of the service, they can consume to service as per usual.

    EDIT: Currently, my ServiceResponse is marked with [DataContract] (as apposed to [ISerializable]
    Thursday, May 15, 2008 2:20 PM

All replies

  • 1) This blog post talks about creating and implementing custom serializers.  So you could create your own serilalizer to serialize to a comman delmited file.

    2) On the client side, it is not going to understand your format unless you manually tell it the format to decode.

    3) Since serialization is declared on the contract, you cant really just have a switch in teh method call.  You will have to have seperate endpoints each with a different contract to the same service.  You may want to look at this too:
    Thursday, May 15, 2008 3:57 PM
  • Dan - thanks for the reply.

    Now I get what I have to do (implement a custom serializer, and declare different endpoints which use the custom serializer and the dataContractSerialzer seperately)

    As to the how: Would the ServiceResponse object declare both the [DataContract] tag (which implemented the DataContractSerializer), and IXMLSerializable interface, and then depending on which endpoint is being used, the specific serializer is implemented?
    For custom serialization (which is not XML), I take it I need to implement IXMLSerializable and override the ReadXml and WriteXml for that kind of serialization control - or is there a different methodolgy.

    Thanks for the info on your blog - quite a few interesting articles.
    Friday, May 16, 2008 8:57 AM
  • Dan

    It's not immediately clear from your blog post as to how to go about creating a custom serializer - seems it just differentiates using DataContractSerializer vs std xml serialization (ala aspx web services). How would I go about implementing a custom serializer that serializes to a delimited string?
    ...and how does this effect the request and response objects being sent over the wire considering that they need to be valid for both endpoints that are defined.
     - It seems that you cannot define [DataContract] attribute, as well as implement IXmlSerializable on the same object.

    PS: if the request and response objects implemented only IXMLSerializable, then theoretically one could pass in a serialization switch in the method, and then check the value of the switch on the ReadXML and WriteXml method overrides of the IXmlSerializable implementation.
    The only reason that I'm not following this path is that I don't want to expose the entire object hierarchy to the consumer who just wants delimited "compact" serialization - hence the definition of 2 different end-points makes more sense.

    As mentioned, the only part I'm missing is how to implement my own custom serializer that will be used by the [XmlSerializerFormat] service endpoint.
    Monday, May 19, 2008 11:25 AM
  • There is some information from MSDN on xml serializer here:



    Tuesday, May 20, 2008 11:45 PM
  • David - thanks for the post, but it doesn't help much.
    What I need (for the custom endpoint that doesn't implement DataContractSerializer), is serialization that doesn't use the xml format at all (verbose tags etc.) - the ServiceResponse object returned needs to serialize into a delimited string, with no xml tags to speak of.

    Maybe I should make my requirements a little clearer? :

    "Blue sky" scenario:
    1) A single service implementation
       eg: MyService { ServiceResponse DoSomething(ServiceRequest request) }

    2) 2 endpoints: 1 implementing DataContractSerializer, and another implementing custom serialization (string delimitation of the object) ie: ServiceResponse will be exposed via DataContractSerializer with all it's fields, but with only a single string field for the CustomSerialization implementation. The service consumer should be able to subscribe to a wsdl definition per endpoint, thus only generating proxy classes for the endpoint which they are using.

       Dan's link on specifying 2 endpoints on the same service shows how to do this
    His post is quite helpful, but falls short of explaining how to consume the seperate endpoints - at the moment I point the client project to the svc file location (which points to a service, not an endpoint - so maybe something can be done here?), which generates proxy classes for both endpoint implementations - I need a way of addressing only a single endpoint.

    For now (until I gain more how-to knowledge), it seems like I'll be dumping the dual endpoints, and just be implementing IXMLSerializable on all the "DataContract" objects (you can't implement [DataContract] and implement IXmlSerializable)
    Then every service method will have a serializeFormat parameter, which the IXmlSerializable implementations (ReadXml(), WriteXml() ) will analyse, and either produce a comma delimited string, or well formed xml.
    The only down-side of this implementation, is that the proxy classes generated will contain the full object definitions for the "DataContract" objects, which is unecessary bloat for a consumer just wishing to implement the custom delimited serialization (that - and to have to specify a SerializeFormat parameter for every method call Indifferent )

    The purpose of all this is the following:
    3rd party consumers should be able to generate full "DataContract" objects from the wsdl, and use the service as per usual.
    For in-house service client (silverlight web application), we should have the ablilty to ignore the object structures (and not expose them) and use prepriotoy serialization logic (which is implemented server and client-side) This facilitates ultra-slim data transfer across the wire, and cuts down on the size of generated proxy classes (which is also initially transferred over the wire to the client)
     - the aim being to improve performance as much as possible across the wire (esp considering 3rd world web infrastructure)
    Wednesday, May 21, 2008 8:39 AM
  • Hmm, if you're going to be serializing just one type, couldn't you go for the "raw" programming model described by Carlos?


    This is easier than building a full-fledged serializer and might be sufficient to get the job done in your case.





    Thursday, May 22, 2008 4:02 AM
  • Yavor,

    Thanks for the post - it's an interesting article.
    The implementation decribed would be 100% for my custom implementation - but then would require that I expose a completely different service to 3rd parties in order for them to get proper return objects. (and generate them from the wsdl exposed from the service)

    What I'm after is "simply" the same service implementation, but different endpoints (which as discussed previously can be achieved by implementing inherited interfaces), each endpoint having it's own wsdl address which expose it's specific format.
    eg: for the DataContractSerializer endpoint, ServiceResponse object would be exposed on it's wsdl as
    ...and be exposed in the XMLFormatSerializer endpoint wsdl as

    Thursday, May 22, 2008 6:38 AM
  • If you go with IXmlSerializable, all the formatting is up to you.  If you use different namespaces, this makes it near impossible to combine both DataContract with IXmlSerializable.
    Friday, May 23, 2008 9:54 PM
  • Look to the
    "The Windows Communication Foundation (WCF) Web Programming Model allows developers to expose WCF service operations to non-SOAP endpoints."
    Maybe this is what you want (avoid XML stuff)
    Saturday, May 24, 2008 5:49 PM
  • Here is an idea that does NOT eliminate xml but dramatically reduces its size to give a performance boost with the xml parser.

    a) have a custom serializer for internal use, that serializes to a "byte" array and dumps the array.
    b) use MtomEncoding, which will detect the byte array and move it outside the soap envelope

    so what you get is a smaller soap envelope that can be parsed fast and a byte array(without a base64 encoding) that can be deserialized back into the runtime objects on the other side (client/server).

    Friday, November 20, 2009 9:37 AM
  • So...does anyone here actually know how to implement a custom serializer for WCF?

    Dan Rigsby's link talks about it, but the example does not work.

    Tuesday, April 20, 2010 3:14 PM
  • For wcf , all you ideally need is a custom message encoder the custom message encoder is all that is required to convert Message to byte array and viceversa. Inorder to use a custom format you will also need a custom impl of the Message unless you want ur custom encoder to tranform to/from your custom format to a supported format such as XML. However, the biggest problem you will have is with encoding soap headers, ur custom format has to support that too. And yes many ppl know how to do it, atleast I can't give out the source due to closed source/nda.
    Tuesday, April 20, 2010 3:49 PM
  • I'm affraid you are talking about something else. The message encoder is one thing and the actual serializer is another.

    What I'm after is to implement a custom serializer for WCF.

    Wednesday, April 21, 2010 12:13 AM