【发布时间】:2014-01-31 16:07:58
【问题描述】:
我们有一个 .NET 客户端,它使用由 wsdl.exe 从 wsdl 文件生成的代理类(派生自 System.Web.Services.Protocols.SoapHttpClientProtocol)。
到目前为止,对于大多数 Web 服务更改,我们在客户端和 Web 服务之间具有良好的兼容性。
旧客户端(具有从旧 wsdl 文件生成的旧代理)不会调用新的 Web 服务方法。
唯一的问题是枚举类型(xsd.enumeration)的扩展。这个特殊的枚举用于许多get... 调用。
示例
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>
从 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 }
错误
客户端知道 枚举 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)
这个错误是正确的,因为它是一个枚举。但我正在寻找一种实用的方法来避免这种异常。您在堆栈跟踪中看到异常是由将响应 XML 数据反序列化为代理的 C# enum 的代码引发的。我们自己的代码已经可以忽略像Yellow 这样的未知枚举值。但是.NET 反序列化并不知道我们的需求。
我已经找到SoapExtensions。但是我需要解析每个 web 服务响应的整个 XML 内容。
您有避免上述异常的想法/解决方案/解决方法吗? 请不要警告我“这很糟糕”、“wsdl 是合同”等。我只想要一个务实的解决方案。 :-)
【问题讨论】:
-
ASMX 是一项遗留技术,不应用于新开发。 WCF 或 ASP.NET Web API 应该用于 Web 服务客户端和服务器的所有新开发。一个提示:微软已经在 MSDN 上停用了ASMX Forum。
-
务实的答案是,如果您将 WSDL 视为合同,您就不会有这些问题。
-
你希望客户端对服务器发送它不理解的数据做什么?
-
为什么不更新客户端呢?更新您的 Web 参考(或服务参考,如果您按照应有的方式使用 WCF),重建您的客户端并重新分发。
-
@JohnSaunders 我知道 ASMX 是一项传统技术。但是当 ASMX 更新时,我们已经开发了这个客户端。现在我们害怕将它转移到 WCF 因为努力。客户端有大约 100,000 行代码。
标签: c# enums .net-3.5 wsdl asmx