none
WebHttpBinding and DataContractSerializer not compatible? RRS feed

  • Question

  • Hi, In the process of developing a RESTful service for consumption by a Silverlight client (and others) we've ran in to a little problem. Consider the following simple service:

     

    Code Snippet

     

    [DataContract]

    [KnownType(typeof(SomeDerivedType))]

    public class SomeType

    {

    [DataMember]

    public string Data { get; set; }

    }

     

    [DataContract]

    public class SomeDerivedType : SomeType

    {

    [DataMember]

    public string SpecializedData { get; set; }

    }

     

    [ServiceContract]

    public interface ISomeService

    {

    [OperationContract, WebGet(UriTemplate = "/GetSome"), ServiceKnownType(typeof(SomeDerivedType))]

    SomeType GetSome();

    }

     
    Accessing this service when it returns the derived type, SomeDerivedType, it responds like this:
     
    Code Snippet
        <Data>the data</Data>
        <SpecializedData>specialized data</SpecializedData>
    </SomeDerivedType>

     

     

    The problem we are having is that we're writing a simple Silverlight client code generator to be able to access these kinds of services and we are using the DataContractSerializer to deserialize/serialize return values/function arguments.
    If we create a DataContractSerializer like this:
     
    DataContractSerializer serializer = new DataContractSerializer(typeof(SomeType), new Type[] { typeof(SomeDerivedType) });
     
    And then, when trying to deserialize the XML above, it throws an exception complaining about that it expected a element with name SomeType instead of SomeDerivedType.
     
    If we do it the other way around, and serialize the data using the same DataContractSerializer we get this XML:
     
    Code Snippet
    <SomeType
        i:type="SomeDerivedType"
        xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"
        xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
        <Data>the data</Data>
        <SpecializedData>specialized data</SpecializedData>
    </SomeType>

     

    The i:type does all the difference.

     

    Another thing i noticed was that if I change the BodyStyle on the service interface to WebMessageBodyStyle.WrappedResponse I get this XML:

     

    Code Snippet

    <GetSomeResponse xmlns="http://tempuri.org/">
        <GetSomeResult
            i:type="a:SomeDerivedType"
            xmlns:a="http://schemas.datacontract.org/2004/07/ConsoleApplication1"
            xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

            <a:Data>the data</a:Data>

            <a:SpecializedData>specialized data</a:SpecializedData>
        </GetSomeResult>
    </GetSomeResponse>

     

     

    Notice that the i:type is specified in this case.

     

    So, how should one do to generate XML that a DataContractSerializer can deserialize from a WebHttpBinding-enabled endpoint (without resorting to WebMessageBodyStyle.WrappedResponse)?

     

    Best regards,

    Andreas Eriksson

    Monday, August 25, 2008 9:16 PM

Answers