鉴于大家对ASP.net十分关注,我们编辑小组在此为大家搜集整理了“在运行时使用 UDDI(2)”一文,供大家参考学习!
在上述结构中,我们突出显示了此 Web 服务的入口点和 bindingKey。这对于客户了解这两部分的信息非常重要。此外,如果某个客户端需要获取此 Web 服务的 WSDL,则可以使用 tModelKey 查询 UDDI 以获取该 tModel。
使用 Web 服务:C# Windows 窗体 .NET 客户端
现在,我们可以转换一下角色,看看应用程序的客户端部分。在设计时,我们也许可以在 UDDI 中找到此 Web 服务。我们将下载相应的 WSDL 文件并使用 Microsoft Visual Studio® .NET 的 Add Web Reference(添加 Web 引用)或 WSDL.exe 生成一个代理类。(WSDL.exe 是一个命令行工具,属于 Microsoft .NET 框架 SDK 的一部分。)
现在可以开始编写客户端应用程序中的逻辑。在本例中,它是称为 SalesReportClient.exe 的 C# Windows 窗体应用程序,允许用户查询销售报表信息。
首先,需要将 UDDI .NET SDK 类添加到项目中,可以下载这些类。(Microsoft UDDI SDK 版本 1.5.2 [英文] 与 Visual Studio .NET Beta 2 兼容;Microsoft UDDI .NET SDK Beta 版本 1.75 [英文] 与 Visual Studio .NET Release Candidate 兼容。) using 声明如下:
using System;using System.Drawing;using System.Collections;using System.ComponentModel;using System.Configuration;using System.Windows.Forms;using System.Data;using Microsoft.Uddi;using Microsoft.Uddi.Binding;
然后,需要将 UDDI 服务器的入口点存储在此 Web 服务所在的位置(毕竟,UDDI 本身就是一个 Web 服务)。要执行此操作,需要为此 .exe 可执行文件创建一个应用程序配置文件,用于存储 UDDI 服务器的位置。Web 服务的 bindingKey 也将存储在此配置文件中。通过在 .NET 中使用 XML 配置文件,您可以添加任意数量的 appSetting,应用程序可以通过集合获取。
<?xml version="1.0" encoding="utf-8" ?><configuration> <appSettings> <add key="UDDI_URL" value="http://localhost/uddi/api/inquire.asmx" /> <add key="bindingKey" value="f46fced9-2b8a-4817-b957-f8d8aca0a2f9" /></appSettings></configuration>
在此示例中,我们指向驻留在自己的计算机上的 Microsoft UDDI Developer Edition 服务器。UDDI_URL 也可以是公共 UDDI 节点之一,或者是驻留在企业内部的 UDDI 注册表。使用配置文件 app.config 的命名规则来保存此文件。编译应用程序后,配置文件将被放在 /bin 目录中,并使用它自己的 .exe 名称命名。
刚刚完成的这个步骤(添加有关 Web 服务的配置信息),与 Visual Studio .NET 如何在添加到项目的每个 Web 引用上公布 URL Behavior 属性并没有什么不同。通过将该属性更改为 dynamic,Visual Studio .NET 可以创建包含 Web 服务入口点的配置文件。上述操作通过提供在运行时重新查询 UDDI 的功能,进一步扩展了此概念。因此,配置文件包含了 UDDI 节点的入口点和 Web 服务的 bindingKey。
现在,我们可以开始对应用程序本身进行编码。首先需要创建一个文本框、一个标签、一个按钮和两个日期时间选择器。然后建立一些全局变量:
//应用程序的一些变量 private string InquiryURL = null; private string bindingKey = null; private string accessPoint = null; private BindingTemplate bt; private double salesFigure = 0;
窗体被实例化以后,我们需要初始化以下变量:
public Form1() { // //Windows 窗体设计器支持所必需 // InitializeComponent(); //从配置文件导入变量 InquiryURL = ConfigurationSettings.AppSettings["UDDI_URL"]; bindingKey = ConfigurationSettings.AppSettings["bindingKey"]; bool InitCache = RefreshCacheFromUDDI(); if ( InitCache == true ) accessPoint = bt.AccessPoint.Text; }
RefreshCacheFromUDDI() 函数用于查询 UDDI 服务器以查找入口点。使用 UDDI SDK 执行 UDDI API 调用 (GetBindingDetail),将 bindingKey 作为参数传递。
private bool RefreshCacheFromUDDI() { //使用 UDDI SDK,设置 UDDI 入口点 Inquire.Url = InquiryURL; //创建 get_bindingDetail UDDI API 消息 GetBindingDetail gbd = new GetBindingDetail(); //添加 bindingKey gbd.BindingKeys.Add( bindingKey ); try { BindingDetail bd = gbd.Send(); //如果成功,则使用返回集合中的第一个模板 //更新 bindingTemplate 对象 bt = bd.BindingTemplates[0]; return true; } catch (Exception err) { textBox1.Text += err.Message; return false; } }
在应用程序运行期间,我们将入口点的位置放在变量中。如果用户要重新启动应用程序,它将在 UDDI 中重新查询入口点,因此应用程序始终拥有对 Web 服务的最新更改。如果需要,可以将这些数据缓存在文件系统或数据库中。
接下来,需要创建调用 Web 服务自身的函数:
private bool InvokeWebService() { localhost.SalesReport sr = new localhost.SalesReport最后,用户单击按钮时,应用程序将尝试调用 Web 服务。private void button1_Click(object sender, System.EventArgs e) { Cursor.Current = Cursors.WaitCursor; //尝试调用 Web 服务 bool WebServiceSuccess = InvokeWebService(); //如果失败,则查询 UDDI if ( WebServiceSuccess == false ) { textBox1.Text += "Web 服务失败。重新查询 UDDI 以获取新的入口点。\n\n"; bool UDDISuccess = RefreshCacheFromUDDI(); //重新查询 UDDI 成功, if ( UDDISuccess == true ) { //将原入口点与新入口点进行比较 //确定是否有所变化 if ( accessPoint.Equals( bt.AccessPoint.Text ) == false) { //如果入口点不同,则一定是新的 //重设变量 accessPoint = bt.AccessPoint.Text; //并尝试再次调用 Web 服务 WebServiceSuccess = InvokeWebService(); //无法使用新信息调用 Web 服务 new info if ( WebServiceSuccess == false ) { textBox1.Text += "Web 服务再次失败。UDDI 中已更新 的入口点无效!\n\n"; } } else { textBox1.Text += "UDDI 未提供新信息。\n\n"; } } else { textBox1.Text += "UDDI 刷新失败。\n\n"; } } }请注意如何在运行时为 Web 服务代理类设置入口点。因为所有代理类都是从 System.Web.Services.Protocols.SoapHttpClientProtocol 中衍生出来的,所以代理类会公布一系列属性,.Url 属性就是其中之一。设置此属性使我们能够在运行时指定入口点。然后,我们可以通过线路发送 SOAP 请求。如果没有发生异常,则表示一切正常并且从 Web 服务返回的数据显示在窗体中。但如果确实发生异常,此函数返回“假”,调用代码将尝试从 UDDI 刷新入口点,以重新使用 RefreshCacheFromUDDI() 函数。重新查询 UDDI 之后,我们会将 UDDI 返回的入口点与原入口点进行比较。如果入口点相同,则提供者尚未使用新信息更新 UDDI,我们所能做的只有尝试与 Web 服务的提供者联系,告诉他们 Web 服务不响应。但是,如果从 UDDI 检索到的入口点不同,则可以尝试再次调用 Web 服务。为模拟故障,可以更改 Web 服务的名称。尝试运行应用程序。然后,用 Web 服务的新名称更新 UDDI 项。再次运行应用程序。应用程序将在 UDDI 中找到新的入口点,成功查询新服务,然后保存此信息。如果您完全关闭应用程序,再重新打开,则第一次尝试时应该能够再次调用 Web 服务。 其他方案这个“失败时重试”示例讨论的是 UDDI 可在运行时用作 Web 服务客户端的支持基础结构。在以后的专栏中,我们将讨论其他方案,包括: 优化入口点查找 - 可能有多个 Web 服务支持驻留在不同服务器上的公共接口,这些服务器又位于不同的物理位置。客户端应使用最近的 Web 服务。通过运行时 UDDI 查找,客户可以根据不同服务的地理分类或与该实现关联的其他元数据来确定最佳入口点。 基于公共接口聚合数据 - WSDL 中可能定义了一种用于搜索目录的标准 Web 服务接口。该行业的很多供应商都可以实现 Web 服务接口,并在 UDDI 中发布入口点。在运行时,客户端应用程序可以动态搜索这些入口点并发出查询以收集这种编录数据。通过这种方式,轮询应用程序可以利用运行时 UDDI 数据。 此外,我们还将讨论如何优化 WSDL 文件,使其真正充当接口说明文件。 总结UDDI 提供了重要的运行时功能,可以集成到应用程序中以创建更强壮的动态客户端。通过将 UDDI 用作 Web 服务体系结构中的基础结构,可以编写更加可靠的应用程序。