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?) ???????? ????}
<
??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 ???? s? :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? >
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这个接口,同样的方法. [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? ????????}
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,它只传输数据,你只要定义发送方和接收方的消息格式就够了. SOA ? ?(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |