首先我們必須了解什麼是webservice就概念上來說可能比較復雜不過我們可以有個宏觀的了解webservice就是個對外的接口裡面有 函數可供外部客戶調用(注意裡面同樣有客戶不可調用的函數)假若我們是服務端我們寫好了個webservice然後把它給了客戶(同時我們給了他 們調用規則)客戶就可以在從服務端獲取信息時處於一個相對透明的狀態即是客戶不了解(也不需要)其過程他們只獲取數據
webservice傳遞的數據只能是序列化的數據典型的就是xml數據這裡我們也只討論xml數據的傳輸
有了一些對xml webservice的初步了解後我們將切入正題即是用一個具體的webservice事例的形式來講解具體的webservice用法用具體的事例來講解一個概念我想怎麼也要比單純的說理能讓人容易理解吧
這裡我們將以一個簡單的分布式課件搜索系統為例來講解使用VS為編譯環境C#為語言SqlServcer為數據庫(這個例子來 源於一位網上朋友的文章的啟發覺得很能代表webservice的特點就按那個想法做了這麼個系統來示例了)
首先明確我們要做什麼我們需要一個對客戶的接口也就是個站點我們把它稱做ServiceGatherSite它是何種形式都無所謂甚至它本身 並不需要數據庫它只是提供給用戶一個查詢的接口真正的服務普通用戶是不接觸到的然後這裡我們還需要若干個提供服務的站點我們可以稱它們為資源 站這裡為簡單起見假設有兩個資源站分別叫WebSiteAWebSiteB它們可以是不對外公布的只是為了豐富查詢數據而存在最後是我們 最需要關注的東西——資源站提供給ServiceGatherSite的服務兩個資源站就有兩個服務我們稱為SiteAService和 SiteBService兩個服務間沒有任何關系內部提供的方法也完全沒關聯只是需要把方法如何使用告訴ServiceGatherSite意思 是服務只提供查詢接口返回的數據如何處理服務本身並不管全由使用服務的站點分配
寫了這麼多算是簡要的介紹了下有關xml webservice的概念和我們這個例子的結構下篇文章我們將開始真正進入代碼的設計階段
上篇文章介紹了些webservice的基本特性和我們例子的結構這篇文章我們將開始具體的代碼編寫工作
這個專題主要講述的是webservice因此這裡我們的代碼以Webservice相關為主而其他工程例如ServiceGatherSiteWebSiteA等只將簡略介紹
在VS中開發一個webservice並不是件困難的事首先我們新建一個webservice項目(文件>新建>項目>C#>Web服務應用程序)
建完這個工程我們將看到一個叫Serviceasmx的文件這就是webservice的標准文件它也有UI的概念不過我們一般不關注因 此我們查看其cs代碼文件如果你什麼都還沒做的話將看見一個被注釋掉的helloworld的WebMethod把注釋去掉在運行你就可以得 到最簡單的webservice運行實例了點擊helloworld將執行其方法顯然這個函數對我們的意義只在於宏觀的了解了下web服務的寫 法
下面我們將開始具體介紹webservice的寫法在代碼文件裡如果我們寫了一個函數後希望此函數成為外部可調用的接口函數我們必須在函數上面 添上一行代碼[WebMethod(Description=函數的描述信息)]如果你的函數沒有這個申明它將不能被用戶引用如
[WebMethod(Description=最簡單的方法)]
public string HelloWorld()
{
return Hello World;
}
這個函數就是外部可調用的接口函數對用戶來說相當於一個API如果某用戶在引用了這個服務後他調用HelloWorld()方法他就將獲得HelloWorld這個返回值
看到這裡我們是不是發現其實webservice並不是那麼的神秘它也不過只是個接口對我們而言側重點依然是接口函數的編寫下面我將給出我們的例子所需要的接口函數
[WebMethod(Description=查詢以獲取需要的課件信息)]
public XmlDataDocument GetSiteAData(string AssignName)
{
XmlDataDocument xd=new XmlDataDocument(); //
DataSet ds=new DataSet();
CStoreProc cp=new CStoreProc(SearchAssign);
cpAddParIn(@keywordsSqlDbTypeVarCharAssignName);
cpAddParOut(@resSqlDbTypeInt);
if(cpSelectProc()) //如果執行成功存儲過程
{
cpmyDataEnforceConstraints=false; //不進行格式嚴格檢查
if((int)cpGetReturnValue(@res)==)
{
string xml=;
xdLoadXml(xml);
return xd;
}
xd=new XmlDataDocument(cpmyData);
XmlNode root=xdDocumentElement;
XmlNodeList roots=rootSelectNodes(list);
foreach(XmlNode roota in roots) //為所有元素加上站點名稱標記
{
XmlElement Link=xdCreateElement(SiteName);
LinkInnerText=ConfigurationSettingsAppSettings[SiteName]ToString();
rootaAppendChild(Link);
}
return xd;
}
else return null;
}
這是獲取資源站點信息的一個接口函數裡面大部分的代碼我想對於有一定基礎的朋友來說都應該是一看就明白這裡只說明下CStoreProc這是我封裝的一個存儲過程類主要功能是執行各種類型的存儲過程
細心的朋友可能會發現這個函數的返回類型似乎比較特殊是個xml的文檔我們在前面已經說過webservice只能傳輸序列化數據xml顯然滿足 條件但比如hash表之類的非序列化數據是不能傳輸的xml使用最為廣泛而且考慮到跨平台應用所以這裡我們只以xml數據的傳輸來示例
[NextPage]
接上篇文章我們先簡單解釋下GetSiteAData(string AssignName)函數
函數功能很簡單只是要返回查詢結果其數據格式是XmlDataDocument當查詢失敗時(無匹配查詢結果)我們構造一個xml返回一個空記 錄否則我們把查詢後的dataset生成一個XmlDataDocument接下來由於該項目的需要我加入了一個循環添加dataset裡所 沒有的節點站點名稱在這之後算是完成了一個符合我們期望格式的xml數據文檔我們把它返回
好了webservice的方法函數介紹完了(這裡還有個web服務方法稍後介紹)接下來我們的任務是怎麼調用它了首先把webservice的 項目編譯完成假定我們這個服務是針對資源站點A的我們不妨稱其為ServiceA先單獨運行asmx文件執行GetSiteAData (string AssignName)方法將提示你輸入參數你輸入要搜索的內容點確認將返回給你一個xml數據並在ie上顯示出來這就是你搜索到的內容拉
這裡對ServiceA的工作再做點介紹在我們這個項目裡它是資源站點A提供的服務意思是它查詢的數據將全來源於站點A而站點A資源添加在本項目也有專門的工程實現
好了回到正題這裡我介紹vs調用webservice的方法其實其他平台的調用方法也是大同小異首先我們介紹web引用方式這種方式我強烈建議 調試時使用非常方便右擊引用點添加web引用輸入你的webservice地址如http //localhost/aspxproject/WebServiceSolution/SiteBService/serviceasmx你必 須保證你輸入的webservice存在然後引用即可注意web引用名將作為你加入的webservice的名字空間比如你輸入了SiteA 那服務的實例化將是這樣SiteAService serviceA=new SiteAService()(Service是服務的類名)
完成了這一步service的調用似乎變的那麼簡單我們已經實現了遠程實例化接下來的遠程調用也是一樣的容易下面給出資源采集站ServiceGatherSite的綁定代碼(只采集A站點的信息)
//綁定數據
public void BindData()
{
serviceA=new SiteAService();
DataSet ds=new DataSet();
XmlNode xmlNode;
XmlDataDocument xd=new XmlDataDocument();
StringBuilder xmlString;
xmlNode=serviceAGetSiteAData(strSearch);
if(xmlNode==null) //存儲過程執行失敗
return;
xmlString=new StringBuilder(xmlNodeOuterXml);
if(xmlStringToString()Equals())
return ;
xdLoadXml(xmlStringToString());
dsReadXml(new XmlNodeReader(xd));
DataGridDataSource=dsTables[list]DefaultView;
DataGridDataBind();
}
此段代碼給出了xml轉化成dataset的解決方案雖然這不是必須的但畢竟在裡dataset占的作用之重誰都知道的其他的請 朋友們先看(呵呵個中高手就免了)在下篇文章中將會有對它的一些解釋與及多服務分布調用的解決方案寫了三篇了發現似乎還是有些朋友看的那我就獻 丑繼續寫下去好了大家有什麼意見也希望提出在下的理解存在偏駁也再所難免希望諒解)
接上篇文章我們先簡單說明下綁定函數首先實例化ServiceA這個和一般類的實例化並沒有不同……接下來用xmlNode來接受函數的返回值接下來是構造xml並將其轉化為dataset這是通用的方法如果是剛接觸不久的朋友最好能記下這種方法
接下來給出異步調用兩個服務的代碼
//綁定數據
public void BindData()
{
IAsyncResult ar;
IAsyncResult ar;
serviceA=new SiteAService();
serviceB=new SiteBService();
DataSet ds=new DataSet();
XmlNode xmlNodexmlNode;
XmlDataDocument xd=new XmlDataDocument();
StringBuilder xmlStringxmlString;
//簡單的異步調用
ar=serviceABeginGetSiteAData(strSearchnullnull);
ar=serviceBBeginGetSiteAData(strSearchnullnull);
xmlNode=serviceAEndGetSiteAData(ar);
xmlNode=serviceBEndGetSiteAData(ar);
//
if(xmlNode==null&&xmlNode==null) //存儲過程執行失敗
return;
xmlString=new StringBuilder(xmlNodeOuterXml);
xmlString=new StringBuilder(xmlNodeOuterXml);
xmlString=MakeNewXmlString(xmlStringxmlString); //生成新的xml
if(xmlStringToString()Equals())
return ;
xdLoadXml(xmlStringToString());
dsReadXml(new XmlNodeReader(xd));
DataGridDataSource=dsTables[list]DefaultView;
DataGridDataBind();
}
//生成新XML
public StringBuilder MakeNewXmlString(StringBuilder strStringBuilder str)
{
str=strReplace();
str=strReplace();
strAppend(strToString());
return str;
}
這有兩個需要注意的地方一個是xml構造還有就是異步調用的實現請讀者自己理解
下面講下通過dll來引用webservice的方法我只把流程介紹下
首先在ie輸入服務的地址如
然後寫輸入?wsdl
打開後另存為xxxwsdl
然後用vs的命令提示符來編譯wsdl /namespaceSiteA ServiceAwsdl
生成名字空間為sitea的代理類
最後csc /outServiceAdll /tlibrary Servicecs 其中servicecs為代理類文件
最後引用dll就可以了
From:http://tw.wingwit.com/Article/program/net/201311/13199.html