** WSE ** ** 使用总结 ** ** **
** 一:概要 ** ** **
1. WSE1.0 Sp1
WSE(Web Service s Enhancements ) 是微软提供的一个实现了 WS-Security, WS-Routing, WS-Attachments and DIME 等标准的组件 (dll) 。它使得开发人员可以不需要深入了解上述协议的具体内容就可以开发相应的 Web Services 程序,大大简化了开发难度,使得 Web Services 应用在企业级项目上成为可能。
2. 常用的几个用途
▲ 添加 / 修改自定义的 SOAP HEADER
▲ 加入身分验证
▲ 加密 SoapBody 信息
▲ 使用附件
▲ 添加 soap router 信息
** 二:设计 ** ** **
2.1 项目的提出:
在一个网上采购系统中,每一个供货方提供给采购方一个 WebServices ,其中有一个提供货物清单的 WebMethod 。这个 WebMethod 的名字可以是不一样的,但其都提供相同的接口。这里,我们假定需要两个入口参数,返回一个 string 类型的 xml 文件。至于为什么假定需要两个参数,在本文后面当有介绍。在实际实现中,接口是可以制定相应规范的,这样也就可以最大限度的重用 proxy 了。
一个采购方希望可以得到最佳的采购方案(本文只讨论技术层次,人际关系,公司关系等不做研究),那么它就会尽可能多的加入更多的供货方。有可能的情况是每天都会有新的供货方加入,因此需要采购方系统是一个可扩展的系统。在本例中,当采购方需要查询一个部件的供货信息的时候,它将使用一个名为 GetAllProduct(string name) 的方法来呼叫所有的 WebServices ,并将得到的返回结果汇总显示。由于本文只是以介绍 WSE 为主,因此不过多讨论系统设计的问题。因为这个项目是我临时杜撰出来,因此在很多方面都不完善,不过我只是描述 WSE 在使用方法,是一个纯粹的技术的讨论。
由于随时都会有新的 WebService 被加入,因此如果我们利用添加 Web 引用的方式加入 Web Services, 那么就把程序写得很死,失去了灵活性和扩展性。因此,我们需要由程序根据 WebServices 的 WSDL 来生成 proxy ,并编译成相应的 DLL 。这里,我们可以人为的定义一个 ServiceID 作为主键来唯一指定一个 WebServices 。在实际开发中,我们将使用 Proxy , Factory 设计模式来进行系统设计,将不同的 WDSL 的 Proxy 的生成, Proxy 的构造封装成相对独立的模块。我们将使用 WSDL.exe 应用程序 , 以及 .net reflecting (反射)的功能 实现。
在调用 WebService 或者接收返回信息的时候,我们可能需要加入一些额外的东西,例如身份认证,定制的 SoapHeader ,加密等操作,这里我将使用微软提供的 WSE1.0 来实现。具体如何实现可以参考微软提供的 quickstart 的例子。其包含在 WSE1.0sp1 的下载包中,具体位置如下 :
2 . 2 proxy 的产生以及使用
1. 根据 WSDL 自动生成 proxy 文件 (PrxoyFactory ,使用 WSDL.EXE)
可以自己制作一个工具,用来根据提供的 WSDL 地址生成 proxy 的 cs 文件。主要代码如下所示:
string parameter = WSDLUrl;
parameter += " /l:C#";
parameter += " /n:" + ServiceID;
parameter += " /o:" + Constants.LIBRARY_PATH + "\" + ServiceID + ".cs";
// Use serviceID as output file name
try
{
ProcessStartInfo startInfo = new ProcessStartInfo(Constants.WSDL_PATH, parameter);
Process process = Process.Start(startInfo);
process.WaitForExit();
if (process.ExitCode != 0)
throw new Exception("generate Proxy error");
return true;
}
catch (Exception ex)
{
}
示例 2.1
2. 修改生成 proxy 文件,将原来的继承 HttpWebClientProtocol 改成 Microsoft.Web.Services.WebServicesClientProtocol
3. 根据数据库内容,为不同的 Proxy 添加不同的 Pipeline ( PipeLineFactory )
每一个 proxy 都会有一个微软提供的默认的 pipeline 。这个 pipeline 将包括了 proxy 需要使用到的 OutputFilter,InputFilter ,并且所有的 Filter 顺序至关重要。因此,我们在设计一个 WebServices 的时候将指定一个唯一的 ServiceID ,并且将其需要使用的 Filter 加入数据库相应的表中。表应该有这个 Filte 的类型 (I/O), 顺序,名字等。:
4. 在 proxy 中, invoke webservice 的方法应该是根据不同的 WebMethod Name 而不同。
如下所示:
object[] results = this.Invoke(pipeline.OperationName, new object[] {
msgID,
sXml});
5. 如果要在 asp.net webservice 中加入 Filter ,目前只能在 global.asax 文件的 application_start() 加入。因此,如果在一个 WebService 中提供了多个 WebMethod, 并且,对于对于不同的 webMethod 可能需要不同的 Filter( 也可能没有 ) 。这种情况下,可以将 WebMethod 分开,做成多个 WebService 。每一个 global.asaz 中的 filter 只对自己所在的 visual folder 的请求 / 响应起作用。
6. 需要注意的是如果我们需要在一个 webservices server 上面加入 filter (提供解密,验证功能) , 那么我们有两种方法作为选择。一种是在 global.asax 文件中的 application_start() 加入全部的 filter ,另外一种是在 web.config 中加入。这样,所有对这个虚拟目录的 soap 请求都会经过这些 filter 。但是,如果这个 WebServices 提供了两个 WebMethod, 并且只有其中的一个需要 filter ,另外一个不需要,上述方法就无法实现了。如何可以动态的为每一个 SOAP 请求分配 filter 一直也是我想知道的问题(类似 proxy 请求端),大家谁知道的也可以告诉我,谢谢。
参考: http://msdn.microsoft.com/webservices/building/wse/default.aspx