運用C#創建一個.Net下的Web Service
2024-07-10 13:01:49
供稿:網友
微軟在其.net戰略中,對其主推的web service做了大肆的宣揚?,F在,web service正如火如荼地發展著,相關的各項新技術層出不窮。web service的發展正構筑著互聯網時代美好的明天。在本文中,我將向大家介紹web service的一些基本知識、如何用c#建立一個web service。通過文章,我們還將對wsdl、uddi以及未來的web service有一個大致的了解。
為什么需要web service?
以前,分布式的應用程序邏輯需要使用分布式的對象模型,通過使用dcom、corba、rmi之類的基本結構,開發人員仍可擁有使用本地模型所提供的豐富資源和精確性,并可將服務置于遠程系統中。
當已經有中意的中間件平臺(rmi、jini、corba、dcom 等等)時,我們為什么還要為web而煩惱呢?中間件確實提供了強大的服務實現手段,但是,這些系統有一個共同的缺陷,那就是它們無法擴展到互聯網上:它們要求服務客戶端與系統提供的服務本身之間必須進行緊密耦合,即要求一個同類基本結構。然而這樣的系統往往十分脆弱:如果一端的執行機制發生變化,那么另一端便會崩潰。例如,如果服務器應用程序的接口發生更改,那么客戶端便會崩潰。為了能擴展到互聯網運用,我們需要一種松散偶合的基本結構來解決這個問題。如此的情況下就迎來了web service的誕生。
什么是web service?
web service 是一種新的web應用程序分支,他們是自包含、自描述、模塊化的應用,可以發布、定位、通過web調用。web service可以執行從簡單的請求到復雜商務處理的任何功能。一旦部署以后,其他web service應用程序可以發現并調用它部署的服務。
web service是一種應用程序,它運用了web網絡技術和基于組件開發的精華成分??梢允褂脴藴实幕ヂ摼W協議,像超文本傳輸協議(http)和xml,將功能綱領性地體現在互聯網和企業內部網上。像dcom、rmi、iiop等基于組件的對象模型已經流行了較長一段時間了。然而這些模型都是依賴于一個特定的對象模型協議。web service擴展了這些模型,使之可以和簡單對象訪問協議(simple object access protocol,soap)以及xml通信以根除特定對象模型協議帶來的障礙??蓪ebservice視作web上的組件編程。(參見如圖1)
web service基本上是利用超文本傳送協議(http)和soap來使商業數據可以在網上獲得。它將商業對象(com對象、java beans等)顯露給在http上的soap調用并執行遠程功能調用。因此,web service的使用者可以在遠程對象上通過soap和http在web上進行方法調用。
圖1
soap調用是一類能引起在位置b上的web service組件程序執行的調用。之后,程序執行的結果就以xml文檔的形式返回給在位置a上的用戶。
在圖1中,在位置a的用戶怎么知道在位置b的用戶的一些情況的呢?這個就要涉及到一個通用標準。服務描述語言(service description language, sdl),soap契約語言(soap contract language,scl)以及網絡可訪問性規格語言(network accessible specification language,nassl)都是為了這個目的而建立的xml類語言。然而,ibm和微軟最近同意將web服務描述語言(web service description language,wsdl)作為web service的標準。
web service組件的結構是通過web服務描述語言來顯露的。wsdl1.1是一個用來描述web service的屬性以及界面的xml文檔。目前已經有了新的規格書,該規格書可以在http://msdn.microsoft.com/xml/general/wsdl.asp上獲得。
面臨的任務
學會web service的最好方法就是自己動手做一個實例。我們都熟悉股票報價服務,納斯達克、道瓊斯都是很著名的例子。它們都提供一個輸入公司代號并取得最新的股票價格的接口。本文我們就設法設計出同樣的功能。
創建web service的工具
本文我們通過ms.net framework sdk來實現這個程序。
創建web service的比較好的集成開發環境(ide)是visual studio.net。然而,你也可以很容易的用任何文本編輯器(記事本、寫字板、visual studio 6.0)來創建一個web service文件。
還有,你必須熟悉以下概念:
net平臺的基礎知識
c#的基礎知識
面向對象概念的基礎知識
創建一個web service
下面,我們將用c#建立一個名為“securitywebservice”的web service。一個web service文件將含有形式為.asmx的擴展名。(就像asp.net的文件擴展名為.aspx)
<%@ webservice language="c#" class="securitywebservice" %>
這條語句將告訴編譯器程序將運行在web service模式下以及c#類的名稱。同時我們要訪問web service的名字空間。還有,最好添加一個對system名字空間的引用。
using system;
using system.web.services;
該securitywebservice的類應該繼承web service類的功能。因此,我們添加了下面這行代碼:
public class securitywebservice : webservice
現在我們來運用我們的面向對象的技巧編寫一個c#類。c#的類和c++、java的類非常相象,如果你有c++和java的基礎,這個就是小菜一碟了。
.net下的web service能夠設定一些基本的數據類型。因此,如果我們返回“int”、“float”或是“string”等數據類型的話,它能自動將它們轉化為標準的xml輸出。然而不巧的是在大多數的情況下,我們需要同一個實體的一類數據集。下面我先舉個例子。我們的securitywebservice股票報價服務要求用戶輸入一個公司的代號,然后它會給出公司的全名以及當前的股票價格。由此,我們需要一個公司的三條信息:
公司代號(數據類型:string)
公司全名(數據類型:string)
股票價格(數據類型:double)
我們需要將單個股票報價的數據信息分解開。可以有很多方法完成此項工作,我們這里用了最好的枚舉數據類型。我們在c#中用了“structs”,和c++中的structs一樣。代碼如下:
public struct securityinfo
{
public string code;
public string companyname;
public double price;
}
現在我們已經完成所有建立web service所需的模塊了。因此,所有的代碼如下:
<%@ webservice language="c#" class="securitywebservice" %>
using system;
using system.web.services;
public struct securityinfo
{
public string code;
public string companyname;
public double price;
}
public class securitywebservice : webservice
{
private securityinfo security;
public securitywebservice()
{
security.code = "";
security.companyname = "";
security.price = 0;
}
private void assignvalues(string code)
{
// 在這里使用商業組件
// 方法調用就是用來獲得所需的數據的
// 本程序中我給相應的代碼添加了一個對應的字符串以方便顯示
// 同時,我使用了隨機數產生器來生成股票價格
security.code = code;
security.companyname = code + " pty ltd";
random randomnumber = new system.random();
security.price = double.parse(new system.random(randomnumber.next(1,10)).nextdouble().tostring("##.##"));
}
[webmethod(description="this method call will get the company name and the price for a given security code.",enablesession=false)]
public securityinfo getsecurityinfo(string code)
{
assignvalues(code);
securityinfo securitydetails = new securityinfo();
securitydetails.code = security.code;
securitydetails.companyname = security.companyname;
securitydetails.price = security.price;
return securitydetails;
}
}
請記住,這個web service能通過http做任何使用。我們也許會在代碼中涉及到一些很敏感的商業數據,但是卻不想它落入他人之手。那解決的方案就是保護一些邏輯函數,使用戶只能訪問到一些用來顯示數據的函數。為了達到這個目的,我們使用了關鍵字“[web method]”。下面就是示例代碼:
[webmethod(description="this......",enablesession=false)]
public securityinfo getsecurityinfo(string code)
這個函數的訪問類型是公有型的。標簽“description”是用來描述這個web service的功能的。因為我們不必儲存任何session數據,所以我們將session狀態設置為false。
private void assignvalues(string code)
這是一個應該被邏輯保護的函數。因為我們不希望我們的商業機密數據能在web被輕易的獲得,所以我們將函數的訪問類型設為private(注:在這里,即使你將函數的訪問類型設為public,這個函數還是不能被公共地訪問到,原因是關鍵字“[web method]”沒有被用到)。
到此,我們可以用getsecurityinfo(string)函數來獲得最新的股票價格。同時,為了方便起見,我給公司代碼添加了相應公司的名字。還有,股票的價格是隨機產生的。
最后,我們將該文件保存在一個由iis控制的目錄下,文件名為“sampleservice.asmx”。運行后的圖示如下:
圖2
以上是一個由.net framework生成的web頁面,我們并沒有創建這個頁面(它是由系統自動產生的,所以我并不需要寫任何代碼來創建該頁面)。這個功能使我們的工作量相對減輕了不少。同樣,你也可以通過運用asp.net的pagelets功能或修改網頁文件使頁面以不同的方式顯示其中的內容。你可以在http://www.ibuyspy.com/store/instantorder.asmx獲得一個很好的例子。
如何使用這個web service?
現在我們來使用這個web service。我們先輸入一些值來獲得股票示例價格。
圖3
按下invoke按鈕,我們就可以獲得以下的xml文檔:
圖4
這樣,這個web service就給用戶提供了其所需的信息了。因為是xml格式的文檔,我們需要寫客戶端來析取這個xml文檔??蛻舳丝梢詾橐韵聨最悾?
1.一個web頁面
2.一個控制臺或是windows下的運用程序
3.一個用wml語言描述的手機程序
4.一個運用在pda上的palm或win ce程序
你可以直接用http get方法來調用這個web service。這樣的話就不會出現第一個頁面了,也不需要用戶去點擊invoke按鈕了。具體方法:
http://server/webservicename.asmx/functionname?parameter=parametervalue
調用我們的web service的方法就是:
http://localhost/work/aspx/sampleservice.asmx/getsecurityinfo?code=ibm
到此為止,我們已經知道如何用c#創建并使用一個web service,但是任務并沒有完全完成。我們需要知道如何在internet上找到我們的web service,我們的web service能不能也被收入在個大搜索引擎。為了解決這個問題,我們就需要建立一個“discovery”文件。
創建發現文件
在訪問一個已有的web service以前,你必須先得找到并整合這個web service,這個過程就是web service的發現過程。通過這個發現過程,你才知道這個web service能為你提供什么樣的服務以及你怎么和它實現互動。發現文件是一個以.disco為擴展名的xml文件。在實際運用中,你是不必為每一個web service創建發現文件的。以下就是一個發現文件的例子:
<?xml version="1.0" ?>
<disco:discovery xmlns:disco="http://schemas.xmlsoap.org/disco/">
<scl:contractref ref="http://localhost/work/aspx/sampleservice.asmx?sdl"/>
</disco:discovery>
我們先將這個文件命名為“sampleservice.disco”,并將它保存在該web service的目錄下。如果我們是在“/work/aspx”目錄下創建web service的話,我們就可以運用更靈活的“動態發現”了?!皠討B發現”能自動為我們檢測“/work/aspx”目錄以及子目錄下的所有*.disco文件的,這樣就省了我們不少功夫。
<?xml version="1.0" ?>
<dynamicdiscovery xmlns="urn:schemas-dynamicdiscovery:disco.2000-03-17">
</dynamicdiscovery>
你可以在http://services3.xmethods.net/dotnet/default.disco獲得一份能使用的發現文件。通過分析發現文件,我們可以找到所需的web service。然而,在得到發現文件前你必須知道這個發現文件的確切的url。否則你還是找不到你要的發現文件的,那么你當然就不能找到你要的web service了。這樣,我們現在就要用到一項新技術了――通用發現,描述和整合(universal description,discovery,and integration,uddi)來為已存在的web service做宣傳了。uddi是公開的,基于internet的。這項技術目前還處于起初階段,所以正不斷發展著。你可以在http://uddi.microsoft.com/ 獲得有關uddi的參考。
發布這個web service
發布web service是很簡單的。和asp.net的程序差不多,你只要將.asmx文件和.disco文件拷貝到相應的目錄,這樣如果一切正常,這個web service就可以工作了。
展望web service的未來
web service技術的前途是相當光明的。在推動web service技術向前發展的道路上,不僅微軟注入了很大的投資,sun、ibm等也表示很大的興趣。同時,網上還有為apache和java 的soap工具包。然而,web service起步不久,還需要很多的工作要做。特別在國內,web service技術起步比國外有晚了一步,所以更要抓緊時間、迎接挑戰。