我们有一个.NET客户端,它使用wsdl.exe从wsdl文件生成的代理类(派生自System.Web.Services.Protocols.SoapHttpClientProtocol
)。
到目前为止,我们在客户端和Web服务之间具有良好的兼容性,可以进行大多数Web服务更改。
旧客户端(具有从旧wsdl文件生成的旧代理)将不会调用新的Web服务方法。
唯一的问题是枚举类型的扩展(xsd.enumeration)。此特殊枚举用于许多get...
次调用。
<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>
[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 }
客户端知道值为Colors
,Red
和Blue
的枚举 Unspecified
。如果服务器返回一个新的枚举值,如Yellow
,我们会收到错误:
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)
此错误是正确的,因为它是 枚举 。但我寻找一种务实的方法来避免这种异常。您在stacktrace中看到,将响应XML数据反序列化为代理的C#枚举的代码抛出异常。我们自己的代码已经可以忽略未知的枚举值,如Yellow
。但.NET反序列化并不了解我们的需求。
我已找到SoapExtensions
。但是,我需要解析每个Web服务响应的整个XML内容。
您是否有想法/解决方案/解决方法以避免上述异常? 请不要警告我“这是坏事”,“wsdl是合同”等等。我只想要一个务实的解决方案。 : - )
答案 0 :(得分:0)
我用SoapExtension做到了。
我使用了TraceExtension示例并对其进行了修改,以便检查每个响应XML是否包含未知的enum
文字。如果找到一个,则扩展名会以未使用的enum
文字(Unspecified
)替换为XML格式。
客户端代码然后忽略文字Unspecified
。
但是还有一个问题:webmethod需要获得SoapExtensionAttribute
(子类)。但是使用该webmethod的代理类是生成的代码(来自* .wsdl)。 因此我们需要在每次生成代码时设置此属性。配置的另一个选项是不可能的,因为我们有一个MMC管理单元,一个* .dll。