none
Problem making modified WCF web service operation compatible with old client RRS feed

  • Question

  • Hi,

    I am trying to make a modified version of a a WCF web service work with old clients. The method signature looks like:

    [OperationContract]        
    itemList GetItemList(getItemList param);

    I am adding elements to the "getItemList" class which should be optional. The class is generated from XSD schema with xsd.exe (this means we are using schema-first design). The new element is:

    <element name="itemOwner" type="string" maxOccurs="1" minOccurs="0">      </element>

    and the new generated code in the getItemList class becomes:

    private string itemOwnerField;        
    public string itemOwner 
    {            
    get {return this.itemOwnerField;}
    set {this.itemOwnerField = value; }
    }

    When I look at the new WSDL it has:

    <xs:element name="itemOwnerField" nillable="true" type="xs:string"/>

    Now I was expecting the old client to still be able to call the new client, since the new field is nillable. The client has a service reference to the old version of the web service so it uses a C# stub. When the old client tries to invoke the new service, I get error:

    The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:param. The InnerException message was 'Error in line 1 position 754. 'Element' 'itemIDField' from namespace 'http://schemas.datacontract.org/2004/07/ServerBaseAPI' is not expected. Expecting element 'itemOwnerField'.'.  Please see InnerException for more details.

    My interpretation is that the server side of the new service cannot deserialize the incoming message since it expects it to contain itemOwnerField. Why it that, when it is nillable according to the WSDL? What can I do to solve or work around the problem?


    Monday, April 27, 2015 1:38 PM

All replies

  • Hi gaor.mawell,

    The nillable attribute is a special attribute in the XML Schema instance namespace that provides an interoperable way to explicitly represent a null value. The receiving end can interpret these as null, zero, and null, respectively. There is no guarantee that a third-party deserializer can make the correct interpretation, which is why this pattern is not recommended. The DataContractSerializer class always selects the correct interpretation for missing values. So have you tried to use the DataMember's IsRequired property? this DataMember's IsRequired property tells the serialization engine whether the value of itemOwnerField must be presented in the underlying XML.
    For more information, please try to refer to the this artcle: https://msdn.microsoft.com/en-us/library/aa347792(v=vs.110).aspx .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.



    Tuesday, April 28, 2015 4:28 AM
    Moderator
  • Hello Amy

    Thanks for the response. I'm starting to realize that my version of the "schema first" approach is so good because some information is lost in the process, it actually goes from XSD to C# and then back to WSDL. For now I will just implement a GetItemList2 method to maintain backward compatibility, but in the long run defining the data contacts in C# using the [DataContract] notation is probably better.

    Best regards,

    Gabriel

    Monday, May 4, 2015 11:27 AM