微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

WebService Interface

WebService Interface? 什么东西? 为什么要这个玩意儿,它有什么用?

有这样一种情况: 我有一个Client程序,要引用到多个Web Service,这一些Web Service的调用方式是一样的,只是各自Web Service本身的实现有一些区别.那么,对于Client来说,最好的调用方式就是这样的:

IObj obj  =   new  WebService1();

obj.Invoke();


obj 
 WebService2();

obj.Invoke();

即通常说到的基于Interface的编程...

但是Web Service的实现和普通的Interface又有一些不同.下面是一个例子,记录了如何使用Web Service Interface.

1. 创建一个接口 ICalculate,加上WebServiceBinding这个Attribute,指明这个Web Service的Name和Namespace:

    [WebServiceBinding(ConformsTo WsiProfiles.BasicProfile1_1,Name " ICalculate ,Namespace http://dev.robinzhong.com/ICalculate/ )]

    
public interface  ICalculate

    
{

        [WebMethod]

        
int Add( a,  b);

        

        [WebMethod]

        
 Sub( b);

    }

2. 创建一个实现了上述接口的类 XCalculate,代码如下:

    [WebService(Namespace  http://tempuri.org/XCalculate/ )]

    [WebServiceBinding(ConformsTo 
 WsiProfiles.BasicProfile1_1,0)">)]

    [ToolBoxItem(
false class  XCalculate : System.Web.Services.WebService,ICalculate

    
{

        
public  Add(  b )

        
{

            
thrownew NotImplementedException( );

        }


        
 Sub(  b )

        

    }


这个地方,不用实现的代码.写这两个东西的目的,是为了得到WSDL的定义,注:仅仅只是此SOAP消息的定义,和具体的Service无关.
访问此Web Service地址,得到其WSLD文件 ( http://localhost:2839/XCalculate.asmx?wsdl ).删除 <wsdl :service />节点.
得到下面的WSDL文件:

<  ?xml  version ="1.0"  encoding ="utf-8" ? >

wsdl  :deFinitions xmlns:soap ="http://schemas.xmlsoap.org/wsdl/soap/"  xmlns:tm ="http://microsoft.com/wsdl/mime/textMatching/"  xmlns:soapenc ="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:mime ="http://schemas.xmlsoap.org/wsdl/mime/"  xmlns:tns ="http://dev.robinzhong.com/ICalculate/"  xmlns:s ="http://www.w3.org/2001/XMLSchema"  xmlns:soap12 ="http://schemas.xmlsoap.org/wsdl/soap12/"  xmlns:http ="http://schemas.xmlsoap.org/wsdl/http/"  targetNamespace  xmlns:wsdl ="http://schemas.xmlsoap.org/wsdl/"

  
</ wsdl >< :types

    
:schema elementFormDefault ="qualified" ="http://dev.robinzhong.com/ICalculate/"

      
s :element name ="Add"

        
:complexType

          
:sequence

            
:element minOccurs ="1"  maxOccurs  name ="a"  type ="s:int" /> ="b"

        

      

      
="AddResponse" ="AddResult" ="Sub" ="SubResponse" ="SubResult"

        

      

    

  
:message name ="AddSoapIn" :part name ="parameters"  element ="tns:Add" ="AddSoapOut" ="tns:AddResponse" ="SubSoapIn" ="tns:Sub" ="SubSoapOut" ="tns:SubResponse" :portType name ="ICalculate" :operation name :input message ="tns:AddSoapIn" :output message ="tns:AddSoapOut" ="tns:SubSoapIn" ="tns:SubSoapOut"

  

  
:binding name ="ICalculate" ="tns:ICalculate" soap  :binding transport ="http://schemas.xmlsoap.org/soap/http" :operation soapAction ="http://dev.robinzhong.com/ICalculate/Add"  style ="document" :input :body use ="literal" :output

    

    
="http://dev.robinzhong.com/ICalculate/Sub"

    

  

  
="ICalculate1" soap12  >


得到了Soap消息的定义和结构,我们就可以用wsdl.exe来生成代码,开始实际的编程工作了.

3. 调用 wsdl.exe /l:cs /n:xxx /out:xxx.cs /si icalculate.wsdl,注意这个/si,完整的参数是 /serverInterface.
生成代码如下:

    [System.CodeDom.Compiler.GeneratedCodeAttribute( 2.0.50727.42 )]

    [System.Web.Services.WebServiceBindingAttribute(Name
)]

    
 IICalculate  {

        

        
/**//// <remarks />

        [System.Web.Services.WebMethodAttribute()]

        [System.Web.Services.Protocols.soapDocumentMethodAttribute(
"http://dev.robinzhong.com/ICalculate/Add=http://dev.robinzhong.com/ICalculate/System.Web.Services.Description.soapBindingUse.Literal, ParameterStyleSystem.Web.Services.Protocols.soapParameterStyle.Wrapped)]

        
 b);

        

        
/**/http://dev.robinzhong.com/ICalculate/Sub b);

    }

注意: 生成的是一个Interface,不是具体的类.这个Interface,就是我所谓的Web Service Interface (其实实质就是WSDL定义).这个Interface的定义和前面定义的ICalculate,除了多一些Attribute外,其它的一模一样.这些个Attribute就是最大的区别,用来定义WebService调用时接收/发送的Soap消息.

4. 即然Interface都出来了.那么这个时候可以写真正的Web Service了,以下是两个Web Service的示例代码:

http://tempuri.org/ http://localhost/WSInterface/ICalculate.wsdl  NewCalculate : System.Web.Services.WebService ,IICalculate

    
{


        [WebMethod]

        
 b )

        
return a + b;

        }


        [WebMethod]

        
 b )

        
-

    }

 

 SimpleCalculate : System.Web.Services.WebService, IICalculate

      b )

        
 b )

        

    }

注意WebServiceBinding这个Attribute,在这两个Web Service类中,都使用了这个Attribute,而且设置其Name="ICalculate",Namespace="http://dev.robinzhong.com/ICalculate"... <font color=red>(注:由于IICalculate接口已定义了WebServiceBindingAttribute,所以在其继承的类中也不必定义此Attribute,ASP.NET 2.0测试通过.)</font>

5. Web Service已写好,下面就是Client的调用代码.同样的,也得先生成IICalculate这个接口,同样的方法.
  wsdl.exe /l:cs /n:xxx /out:xxx.cs /si icalculate.wsdl

得到IICalcuate接口.
然后再添加上面两个Web Service中任意一个WebService的引用.比如NewCalculate这个Web Service,得到如下代码:

[System.CodeDom.Compiler.GeneratedCodeAttribute( System.Web.Services )]

    [System.Diagnostics.DebuggerStepThroughAttribute()]

    [System.ComponentModel.DesignerCategoryAttribute(
code )]

    
 partial  CalculateProxy : System.Web.Services.Protocols.soapHttpClientProtocol  {

        

        
private System.Threading.SendOrPostCallback AddOperationCompleted;

        

        
 System.Threading.SendOrPostCallback SubOperationCompleted;

        

        
bool useDefaultCredentialsSetExplicitly;

        

修改此类,让其从IICalculate继承.然后修改构造函数,让其通过构造函数得到Web Service的Url.如下:

)]

     : System.Web.Services.Protocols.soapHttpClientProtocol,IICalculate 

 useDefaultCredentialsSetExplicitly;

        

        
/**/<remarks/>

        
CalculateProxy (string url) 

this.Url  url;

            
if ((.IsLocalFileSystemWebService(.Url) ==true)) 

{

                
.UseDefaultCredentials ;

                
.useDefaultCredentialsSetExplicitly false;

            }

            
else 


        }


6. 好了,可以开始测试我们的代码了:

IICalculate calculate;


calculate   CalculateProxy(  http://localhost:2935/SimpleCalculate.asmx );

Console.WriteLine( 
calculate.Add( 10, 345 ) =  +  calculate.Add(  10 345  ) );

Console.WriteLine( 
calculate.Sub( 3455, 234 ) =   calculate.Sub(  3455 234  ) );


calculate 
http://localhost:2935/NewCalculate.asmx  ) );

这样就达到了Web Service Interface的目的了--我不管是那里的Web Service,反正只要实现了上面的接口,给我正确的URL地址,我就可以调用...

其实,我们可以用更幽雅的方式实现: Contract First . Web Service不是RPC,它只传输数据,你只要定义发送方和接收方的消息格式就够了.
推荐大家看看 :
http://www.thinktecture.com/Resources/Software/WSContractFirst/default.html
http://msdn.microsoft.com/msdnmag/issues/05/05/ServiceStation/

SOA ?

:)

 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐