WCF 对 WSDL 2.0 的支持





5.00/5 (1投票)
一个命令行实用程序,用于从 WSDL 2.0 文档生成 WCF 代理。
引言
Windows Communication Foundation (WCF) 是 Microsoft 最新的 SOAP 堆栈(以及更多)。SOAP 堆栈使程序员可以使用他们最喜欢的编程模型(类),而不是手动创建 SOAP 消息。 WCF 从 WSDL 生成这些类(代理),WSDL 是每个 Web 服务公开的元数据文件,其中包含它支持的操作及其架构的列表。 WCF 只知道从 WSDL 1.0 文档生成类(代理)。
在本文中,我将展示如何扩展 WCF,以便它也可以从 WSDL 2.0 文档生成类。
背景
许多 Web 服务的主要要求是支持互操作性。 这意味着来自各种平台的客户端应该能够访问 Web 服务。 关键在于各个平台生成代理的能力,这样就无需像这样手动创建 SOAP(高度简化)。
<Envelope>
<Body>
<AddUser>
<Name>Yaron</Name>
<Blog>http://webservices20.blogspot.com/</Blog>
<Books>
<Book>
<Name>My First book</Name>
</Book>
...
</Books>
</AddUser>
</Body>
</Envelope>
开发人员可以使用像这样的类
public class User
{
string Name;
Uri Blog;
Book[] Books;
}
是不是更好?如果 Web 服务公开 WSDL 文件,则 SOAP 堆栈可以生成这样的类。 此文件包含生成代码所需的所有元数据。 这是一个来自 WSDL 的(小的)示例
<s:element name="EchoString">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1"
name="s" type="s:string" />
</s:sequence>
</s:complexType>
</s:element>
...
<WSDL:message name="EchoStringSoapIn">
<WSDL:part name="parameters" element="tns:EchoString" />
</WSDL:message>
...
<WSDL:operation name="EchoString">
<WSDL:input message="tns:EchoStringSoapIn" />
<WSDL:output message="tns:EchoStringSoapOut" />
</WSDL:operation>
此 WSDL 遵循 WSDL 1.0 版本,这是流行的版本。较新的版本 WSDL 2.0 并不常见。 它会成为现实吗?它会实现成为 REST 和 SOAP 服务的下一代元数据的承诺吗? 这个有趣的讨论超出了本文的范围。 如果您有兴趣,请在此博客中阅读一些内容。
许多 SOAP 堆栈仅支持从 WSDL 1.0 文档生成客户端。 WCF 就是其中之一。 如果您尝试为使用 WSDL 2.0 的服务编写 WCF 客户端,这可能会非常痛苦。
在本文中,我将展示如何使用 WCF 使用 WSDL 2.0 文档。
使用代码
- 从附加到本文的源代码或从 CodePlex 项目页面下载最新版本的 svcutil2.exe。
- 打开 VS 命令控制台,或者确保原始的 svcutil.exe 位于当前路径中(通常位于 C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin))。
- 像使用 svcutil 一样使用 svcutil2
$> svcutil2.exe http://WSDL2WSDL.cloudapp.net/WSDL/simple2.WSDL
您也可以使用任何 svcutil 已知的标志。
实现
为 WSDL 编写代码生成是一项复杂的任务。 我选择使用一种不同的方法:我利用了 WCF 已经知道从 WSDL 1.0 文档生成代码的事实,因此我将 WSDL 2.0 文档转换为 WSDL 1.0 并将其交给 WCF 进行处理。 svcutil2 基于与 WSDL2WSDL 相同的代码库,后者是一个在线 WSDL2 → WSDL1 转换器实用程序。
实际转换的细节非常繁琐,但欢迎您研究 WSDL2WSDLConverter.cs 类以获取完整详细信息。
关注点
一些读者可能会问,如果可以将 WSDL 2.0 简化为 WSDL 1.0 文档,那么 WSDL 2.0 还有什么用处呢? 事实是 WSDL 2.0 比 WSDL 1.0 包含更多内容,但对于 SOAP 堆栈来说,大多数新内容都不相关。 其中一些是相关的,我不得不使用创造性的方法来解决它,或者将其作为此版本中的限制。 一个例子是当前不支持的接口继承。