首先我覺得有必要把.net平臺下開發webservice進行一個比較全面的闡述,web service的最初產生是在電子商務的環境下出現的,有些問題通過傳統的手段已經不容易解決,比如在應用程序之間進行商務通信、數據交換,使用DCom、CORBA等二進制機制的東西已經行不通了,姑且不說他們受各自平臺的限制,比如DCom(Distribute Common Objects Model)只能在Windows平臺下進行,而CORBA(Common Objects Request Broker Architecture)又只是Java平臺下的產物。他們要實現應用程序之間的數據通信是比較困難的。 在這種背景下,Web Services 應運而生,它很好的解決了跨語言、跨平臺以及良好而安全的穿透企業防火墻。它的體系結構大體上分為五個層次: HTTP(HyperText Transfer Protocol)信道下進行數據通信 XML(Extensable Markup Language)數據表達形式 SOAP(Simple Objects Access Protocol)的數據封裝 WSDL(WebServices Description Language)的描述語言格式 UDDI(Universal Description and Discovery Integration) 統一的描述、發現和集成 作為它的優點跨語言、跨平臺以及良好而安全的穿透企業防火墻已經足以使我們感到興奮了。不過它也存在需要改善的地方,比如: HTTP進行數據通信存在速度較慢的情況,尤其是第一次聯結。 需要一臺Web Server這一額外的開銷 說了WebServices的體系結構以及其優點缺點以后我們切入正題,那就是我們這次討論的話題: Web Service 服務在Delphi下調用時的問題 閑話少說,我們用一個檢驗WebMethod的Attribute的一個簡單的例子進行闡述:它是完成一次從客戶A轉帳到B的一個簡單商務過程。 首先我們在.NET FrameWork1.1下創建一個WebService,這時候.net會幫我們自動創建一個Web應用 我們需要創建一個類AttributeTest,它是在命名空間NameSpace AttributeTesting下的,那么這個類它將自動繼承了它的基類 System.Web.Services.WebService,需要支出的時,我們可以對這個Web應用類設置其WebServiceAttribute,其中基本屬性包括Description 和NameSpace [WebServiceAttribute(Namespace="http://www.isdoo.com/services", Description="Hello Ansel,This is a testing Web Service!")] public class AttributeTest : System.Web.Services.WebService { [WebMethodAttribute(Description="描述信息:繼承了Count方法,并且對名稱進行重載。執行的是把錢從A用戶轉帳到B用戶......", //MessageName="Changing MessageName", BufferResponse=true, CacheDuration=1000, EnableSession=true, TransactionOption=TransactionOption.RequiresNew)] public string transMoney(double Money) { try { ContextUtil.EnableCommit();//Transaction only used to Database operation! MoneyInToA(Money); MoneyOutFromB(Money); ContextUtil.SetComplete(); return "Transaction Successful,total "+Money.ToString(); } catch( Exception e) { ContextUtil.SetAbort(); return "Transaction failed! \n\r "+e.Message; } } private void MoneyInToA(double Money) { SqlCommand sqlCom = new SqlCommand("update budget set Money=Money+"+Money.ToString()+" where Name='A'"); databaseAccess myDatabase = new databaseAccess(); sqlCom.Connection=myDatabase.getConnection(); sqlCom.Connection.Open(); sqlCom.ExecuteNonQuery(); sqlCom.Connection.Close(); //throw new Exception("Operation failed when transfer money into A!"); } private void MoneyOutFromB(double Money) { SqlCommand sqlCom = new SqlCommand("update budget set Money=Money-"+Money.ToString()+" where Name='B'"); databaseAccess myDatabase = new databaseAccess(); sqlCom.Connection=myDatabase.getConnection(); sqlCom.Connection.Open(); sqlCom.ExecuteNonQuery(); sqlCom.Connection.Close(); //throw new Exception("Operation failed when transfer money from B!"); } } 其中我們需要特別注意的是,WebMethodAttribute,這也是我們這一次需要講述的重點內容,只要給一個方法加上[WebMethodAttribute],哪怕里面沒有任何屬性,那么WebService就會把這個方法暴露(Expose)給了客戶段調用者.下面我們講述一下它的6個屬性,其中包括2個描述性的信息屬性,4個功能屬性 描述性的信息屬性: Description MessageName 4個功能性屬性: BufferResponse CacheDuration EnableSession TransactionOption 其中我們需要注意MessageName這個屬性它Delphi調用.NET平臺下開發的WebService的時候,如果你設置了MessageName這個Attribute的話,那么客戶端調用時會報錯誤。這也許是一個Bug,或許后面的版本會解決這個問題。至于這幾個屬性的具體功能就不再這里詳細描述了。大家可以去看看相關的書籍。 下面我把Delphi調用webservice的步驟列舉一下: 首先如果你只是開發調用客戶端,那么你只需要創建一個普通的應用程序即可,然后需要你做的是,在工具欄WebServices下面找到SOAPHTTPClient這個控件,然后把它放在你的客戶端應用窗體上; 其次就是你需要設置這個SOAPHTTPClient的屬性URL或者WSDL,這個內容就是你的WebService的服務地址 比如我們當前例子的服務地址是:http://localhost/AttributeTesting/AttributeTesting.asmx 如果你想輸入WSDL那么就是http://localhost/AttributeTesting/AttributeTesting.asmx?wsdl 這樣就完成了控件設置; 然后我們需要引入服務器端的WSDL,你可以手工來做,也可以用Delphi提供的WebServices Importer功能來引入。 最后你只需要對引入的WSDL的接口進行調用即可。在這里我們的對應代碼是: procedure TForm1.BitBtn1Click(Sender: TObject); var aa:AttributeTestSoap;//這個就是WSDL下的類接口對象 msg:widestring; bb:double; begin //HTTPRIO2 其實就是所謂的代理類,它負責進行數據傳輸發送Request和接受Response的 aa:=HTTPRIO2 as AttributeTestSoap; bb:=100.00; msg:=aa.transMoney(bb);//這就是調用web服務所暴露給我們的web服務方法WebMethod showmessage(msg); end; Ok! That's all!
|