XML WebService完全執行個體詳細解析

來源:互聯網
上載者:User
web|xml

  首先,我們必須瞭解什麼是webservice.就概念上來說,可能比較複雜,不過我們可以有個宏觀的瞭解:webservice就是個對外的介面,裡面有 函數可供外部客戶調用(注意:裡面同樣有客戶不可調用的函數).假若我們是服務端,我們寫好了個webservice,然後把它給了客戶(同時我們給了他 們調用規則),客戶就可以在從服務端擷取資訊時處於一個相對透明的狀態.即是客戶不瞭解(也不需要)其過程,他們只擷取資料.

  webservice傳遞的資料只能是序列化的資料,典型的就是xml資料,這裡我們也只討論xml資料的傳輸.

  有了一些對xml webservice的初步瞭解後,我們將切入正題,即是用一個具體的webservice案例的形式來講解具體的webservice用法,用具體的案例來講解一個概念我想怎麼也要比單純的說理能讓人容易理解吧.

  這裡,我們將以一個簡單的分布式課件搜尋系統為例來講解.使用VS2003為編譯環境,C#為語言,SqlServcer2000為資料庫.(這個例子來 源於一位網上朋友的文章的啟發,覺得很能代表webservice的特點,就按那個想法做了這麼個系統來樣本了)

  首先,明確我們要做什麼.我們需要一個對客戶的介面,也就是個網站,我們把它稱做ServiceGatherSite,它是何種形式都無所謂,甚至它本身 並不需要資料庫,它只是提供給使用者一個查詢的介面,真正的服務,普通使用者是不接觸到的.然後,這裡我們還需要若干個提供服務的網站,我們可以稱它們為資源 站,這裡為簡單起見,假設有兩個資來源站點,分別叫WebSiteA,WebSiteB,它們可以是不對外公布的,只是為了豐富查詢資料而存在.最後,是我們 最需要關注的東西---資來源站點提供給ServiceGatherSite的服務.兩個資來源站點,就有兩個服務,我們稱為SiteAService和 SiteBService.兩個服務間沒有任何關係,內部提供的方法也完全沒關聯,只是需要把方法如何使用告訴ServiceGatherSite,意思 是,服務只提供查詢介面,返回的資料如何處理,服務本身並不管,全由使用服務的站台指派.

  寫了這麼多,算是簡要的介紹了下有關xml webservice的概念和我們這個例子的結構,下篇文章,我們將開始真正進入代碼的設計階段.

  上篇文章介紹了些webservice的基本特性和我們例子的結構,這篇文章我們將開始具體的代碼編寫工作.

  這個專題主要講述的是webservice,因此這裡我們的代碼以Webservice相關為主,而其他工程,例如:ServiceGatherSite,WebSiteA等,只將簡略介紹.

  在VS2003中,開發一個webservice並不是件困難的事,首先,我們建立一個webservice項目(檔案->建立->項目->C#->Web服務應用程式)

  建完這個工程,我們將看到一個叫Service1.asmx的檔案,這就是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");
  cp.AddParIn("@keywords",SqlDbType.VarChar,30,AssignName);
  cp.AddParOut("@res",SqlDbType.Int);
  if(cp.SelectProc()) //如果執行成功,預存程序
  {
  cp.myData.EnforceConstraints=false; //不進行格式嚴格檢查
  if((int)cp.GetReturnValue("@res")==-1)
  {
  string xml="";
  xd.LoadXml(xml);
  return xd;
  }
  xd=new XmlDataDocument(cp.myData);
  XmlNode root1=xd.DocumentElement;
  XmlNodeList roots=root1.SelectNodes("list");
  foreach(XmlNode roota in roots) //為所有元素加上網站名稱標記
  {
  XmlElement Link=xd.CreateElement("SiteName");
  Link.InnerText=ConfigurationSettings.AppSettings["SiteName"].ToString();
  roota.AppendChild(Link);
  }
  return xd;
  }
  else return null;
  }

  這是擷取資來源站點點資訊的一個介面函數.裡面大部分的代碼,我想對於有一定asp.net基礎的朋友來說,都應該是一看就明白,這裡只說明下CStoreProc,這是我封裝的一個預存程序類,主要功能是執行各種類型的預存程序.

  細心的朋友可能會發現這個函數的傳回型別似乎比較特殊,是個xml的文檔.我們在前面已經說過,webservice只能傳輸序列化資料,xml顯然滿足 條件,但比如hash表之類的非序列化資料,是不能傳輸的,xml使用最為廣泛,而且考慮到跨平台應用,所以這裡我們只以xml資料的傳輸來樣本.

  接上篇文章,我們先簡單解釋下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/service1.asmx,你必 須保證你輸入的webservice存在.然後引用即可,注意:web引用名將作為你加入的webservice的名字空間.比如你輸入了:SiteA, 那服務的執行個體化將是這樣:SiteA.Service1 serviceA=new SiteA.Service1();(Service1是服務的類名).

  完成了這一步,service的調用似乎變的那麼簡單,我們已經實現了遠程執行個體化,接下來的遠程調用也是一樣的容易.下面給出資源採集站ServiceGatherSite的綁定代碼(只採集A網站的資訊)

  //綁定資料
  public void BindData()
  {
  serviceA=new SiteA.Service1();
  DataSet ds=new DataSet();
  XmlNode xmlNode1;
  XmlDataDocument xd=new XmlDataDocument();
  StringBuilder xmlString1;
  xmlNode1=serviceA.GetSiteAData(strSearch);
  if(xmlNode1==null) //--預存程序執行失敗
  return;
  xmlString1=new StringBuilder(xmlNode1.OuterXml);
  if(xmlString1.ToString().Equals(""))
  return ;
  xd.LoadXml(xmlString1.ToString());
  ds.ReadXml(new XmlNodeReader(xd));
  DataGrid1.DataSource=ds.Tables["list"].DefaultView;
  DataGrid1.DataBind();
  }

  此段代碼給出了xml轉化成dataset的解決方案,雖然這不是必須的,但畢竟在asp.net裡,dataset占的作用之重,誰都知道的.其他的請 朋友們先看(呵呵,箇中高手就免了),在下篇文章中將會有對它的一些解釋與及多服務分布調用的解決方案,寫了三篇了,發現似乎還是有些朋友看的,那我就獻 醜繼續寫下去好了,大家有什麼意見也希望提出,在下的理解存在偏駁也再所難免,希望諒解:)

  接上篇文章,我們先簡單說明下綁定函數.首先執行個體化ServiceA,這個和一般類的執行個體化並沒有不同..接下來用xmlNode1來接受函數的傳回值,接下來是構造xml,並將其轉化為dataset,這是通用的方法,如果是剛接觸不久的朋友,最好能記下這種方法.

  接下來給出非同步呼叫兩個服務的代碼

  //綁定資料
  public void BindData()
  {
  IAsyncResult ar1;
  IAsyncResult ar2;
  serviceA=new SiteA.Service1();
  serviceB=new SiteB.Service1();
  DataSet ds=new DataSet();
  XmlNode xmlNode1,xmlNode2;
  XmlDataDocument xd=new XmlDataDocument();
  StringBuilder xmlString1,xmlString2;
  //--簡單的非同步呼叫
  ar1=serviceA.BeginGetSiteAData(strSearch,null,null);
  ar2=serviceB.BeginGetSiteAData(strSearch,null,null);
  xmlNode1=serviceA.EndGetSiteAData(ar1);
  xmlNode2=serviceB.EndGetSiteAData(ar2);
  //----------
  if(xmlNode1==null&&xmlNode2==null) //--預存程序執行失敗
  return;
  xmlString1=new StringBuilder(xmlNode1.OuterXml);
  xmlString2=new StringBuilder(xmlNode2.OuterXml);
  xmlString1=MakeNewXmlString(xmlString1,xmlString2); //產生新的xml
  if(xmlString1.ToString().Equals(""))
  return ;
  xd.LoadXml(xmlString1.ToString());
  ds.ReadXml(new XmlNodeReader(xd));
  DataGrid1.DataSource=ds.Tables["list"].DefaultView;
  DataGrid1.DataBind();
  }
  //產生新XML
  public StringBuilder MakeNewXmlString(StringBuilder str1,StringBuilder str2)
  {
  str1=str1.Replace("","");
  str2=str2.Replace("","");
  str1.Append(str2.ToString());
  return str1;
  }

  這有兩個需要注意的地方,一個是xml構造,還有就是非同步呼叫的實現,請讀者,自己理解

  下面講下通過dll來引用webservice的方法,我只把流程介紹下.

  首先,在ie輸入服務的地址,如:http://www.xxx.com/service.asmx

  然後寫輸入http://www.xxx.com/service.asmx?wsdl

  開啟後,另存新檔xxx.wsdl

  然後用vs的命令提示字元來編譯:wsdl /namespace:SiteA ServiceA.wsdl

  產生名字空間為sitea的代理類

  最後csc /out:ServiceA.dll /t:library Service1.cs ,其中service1.cs為代理類檔案

  最後引用dll就可以了.



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。