Question

We have a .NET client that uses a proxy class (derived from System.Web.Services.Protocols.SoapHttpClientProtocol) generated from a wsdl file by wsdl.exe.

Up to now we have a good compatibility between client and webservice for the most webservice changes. An old client (with old proxy that is generated from an old wsdl file) would just not call the new webservice methods.
The only problem is an extension of an enum type (xsd.enumeration). This special enum is used in many get... calls.

Example

WSDL

  <xsd:simpleType name="Colors">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="Red"/>
      <xsd:enumeration value="Blue"/>
      <xsd:enumeration value="Unspecified"/>
    </xsd:restriction>
  </xsd:simpleType>

Proxy code generated from WSDL

[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:archive.admin.services.ecm.opentext.com")]
public enum Colors { Red, Blue, Unspecified }

Error

Client knows the enum Colors with values Red, Blue and Unspecified. If server returns a new enum value like Yellow we get the error:

Instance validation error: 'Yellow' is not a valid value for Colors.
Exception Class: System.InvalidOperationException
StackTrace:
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderArchiveAdministrationService.Read2_Keys(String s)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderArchiveAdministrationService.Read6_ResultField(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderArchiveAdministrationService.Read7_ResultRecord(Boolean isNullable, Boolean checkType)
   at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderArchiveAdministrationService.Read10_invokeCommandResponse()
   at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer.Deserialize(XmlSerializationReader reader)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
There is an error in XML document (1, 1557).
Exception Class: System.InvalidOperationException
StackTrace:
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
   at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)

This error is correct because it is an enumeration. But I looking for a pragmatic way to avoid this exception. You see in stacktrace that the exception is thrown by code that deserializes the response XML data to proxy's C# enum. Our own code can already ignore an unknown enum value like Yellow. But the .NET deserialization doesn't know our needs.

I have already found SoapExtensions. But then I would need to parse the whole XML content of every webservice response.

Do you have an idea/solution/workaround to avoid above exception? Please don't warn me that "this is bad", "wsdl is a contract" and so on. I want just a pragmatic solution. :-)

Was it helpful?

Solution

I did it with a SoapExtension. I took the TraceExtension sample and modified it so that every response XML is checked for unknown enum literals. If one is found the extension replaces it in XML by an unused enum literal (Unspecified).
The client code ignores the literal Unspecified then.

But one problem left: The webmethod needs to get the SoapExtensionAttribute (sub class). But the proxy class with that webmethod is generated code (from a *.wsdl). So we need to set this attribute every time the code is generated. The other option by configuration is imo not possible because we have a MMC Snap-In, a *.dll.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top