自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

C# WebService調(diào)用的三大難題

開發(fā) 后端
本文向您介紹C++與C#互相通信,C# WebService調(diào)用的三個難點。用C#編寫客戶端時,只需要將WebService添加到引用,就能像調(diào)用本地方法一樣去C# WebService調(diào)用。

一、用C#實現(xiàn)WebService是相當(dāng)簡單的事情,我們只要創(chuàng)建一個Web服務(wù)程序,在方法名上面加上[WebMethod],部署到IIS上,就能像訪問Web站點一樣訪問WebService。

用C#編寫客戶端時,只需要將WebService添加到引用,就能像調(diào)用本地方法一樣去C# WebService調(diào)用。像這樣的例子也比比皆是,在這就不多講。

二、用C++實現(xiàn)WebService,一般會用到gsoap,具體方法見:http://www.cppblog.com/qiujian5628/archive/2008/06/19/54019.html

三、當(dāng)做完了這些之后,并不代表WebService就能相互通訊了,現(xiàn)在我簡單列舉一下問題:

1、C#提供的WebService的URL一般形如:http://localhost/WebService.asmx,但是,C++能提供的只能是:http://localhost/。C++做客戶端的時候調(diào)用沒有問題,但是當(dāng)C#做客戶端的時候,引用C++提供的RUL時,會提示沒用執(zhí)行方法(HTTP GET method not implemented)。做C#開發(fā)的大部分會認(rèn)為C++方提供的不是WebService,或者說提供的WebService根本就不全,都不帶.asmx文件。做C++開發(fā)的會認(rèn)為他傳輸?shù)臄?shù)據(jù)符合soap協(xié)議,靠http傳輸數(shù)據(jù),他就是WebService。

2、當(dāng)我們解決了第一步后,緊接著會發(fā)現(xiàn)另外一個問題。當(dāng)我們需要傳輸自定義數(shù)據(jù)類型時(在C++中稱結(jié)構(gòu)體,在C#中稱實體),從C++返回的信息中,C#無法構(gòu)建出實體類。

3、當(dāng)傳輸?shù)男畔⒅袔в兄形淖址麜r,亂碼滿天飛。

四、為了解決這些問題,我們先簡單了解一下WebService。

Web Service互操作協(xié)議棧:

〈A〉、服務(wù)發(fā)現(xiàn) (UDDI)

〈B〉、服務(wù)描述(WSDL)

〈C〉、服務(wù)調(diào)用(SOAP)

〈D〉、消息編碼 (XML)

〈E〉、傳輸網(wǎng)絡(luò)層(HTTP, TCP/IP)

其中WSDL描述WebService都有什么方法、方法有什么參數(shù),什么返回值等。SOAP(簡單對象訪問協(xié)議(Simple Object Access Protocol)是一種輕量的、簡單的、基于XML的協(xié)議。傳輸?shù)臄?shù)據(jù)就需要遵循這個協(xié)議。我比較簡單得認(rèn)為傳輸?shù)臄?shù)據(jù)需要遵循這種格式。

借用微軟的這個圖描述下WebService的調(diào)用過程:

C# WebService調(diào)用

五、開始解決問題。作為.NET開發(fā)人員,我們根本就接觸不到底層的東西,全被封裝了。

C++做的確實是WebService,只是他們需要給提供一個描述文檔,即.WSDL文件。使用.NET提供的wsdl.exe工具,使用命令:wsdl /o: c:\webservice.cs c:\webservice.wsdl。通過webservice.wsdl文檔,生成代理類,將代理類寫入webservice.cs文件中。我們拷貝這個cs文件到項目中,將URL指向http://localhost/,就能像以往那樣使用WebService了。

當(dāng)出現(xiàn)無法傳遞復(fù)雜類型數(shù)據(jù)時,是因為使用gsoap生成的wsdl文件與.Net中生成的wsdl文件不一樣。具體代碼如下:

  1. 〈!--operationresponseelement--〉  
  2. 〈elementname="result"〉  
  3. 〈complexType〉  
  4. sequence〉  
  5. 〈elementname="a"type="xsd:int" 
  6. minOccurs="1"maxOccurs="1"/〉  
  7. 〈elementname="b"type="xsd:int" 
  8. minOccurs="1"maxOccurs="1"/〉  
  9. 〈/sequence〉  
  10. 〈/complexType〉  
  11. 〈/element〉  
  12. 以上為gsoap生成的。返回實體result,  
  13. 實體有兩個屬性:a,b。  
  14. 〈s:elementname="TestResponse"〉  
  15. 〈s:complexType〉  
  16. 〈s:sequence〉  
  17. 〈s:elementminOccurs="0"maxOccurs="1" 
  18. name="TestResult"type="tns:result"/〉  
  19. 〈/s:sequence〉  
  20. 〈/s:complexType〉  
  21. 〈/s:element〉  
  22. 〈s:complexTypename="result"〉  
  23. 〈s:sequence〉  
  24. 〈s:elementminOccurs="1"maxOccurs="1" 
  25. name="a"type="s:int"/〉  
  26. 〈s:elementminOccurs="1"maxOccurs="1" 
  27. name="b"type="s:int"/〉  
  28. 〈/s:sequence〉  
  29. 〈/s:complexType〉  
  30. 以上是.NET生成的。  
  31.  
  32. 在下面的文件中,多出  
  33. 〈s:elementname="TestResponse"〉  
  34. 〈s:complexType〉  
  35. 〈s:sequence〉  
  36. 〈s:elementminOccurs="0"maxOccurs="1" 
  37. name="TestResult"type="tns:result"/〉  
  38. 〈/s:sequence〉  
  39. 〈/s:complexType〉  
  40. 〈/s:element〉  
  41.  

這個便是.NET中用來構(gòu)造實體的。當(dāng)我們出現(xiàn)情況4.2時,gsoap中盡量使用.NET生成的wsdl文檔,生成.h文件,以避免C++中的結(jié)構(gòu)無法在C#中轉(zhuǎn)換成實體。

第三個問題,我們是通過將中文轉(zhuǎn)換成16進(jìn)制后傳輸過來,然后再轉(zhuǎn)換成中文。下面提供C#轉(zhuǎn)換的代碼:

  1. ///〈 summary 〉  
  2. ///從16進(jìn)制轉(zhuǎn)換成漢字  
  3. ///〈 /summary 〉  
  4. ///〈 paramname="hex" 〉〈 /param 〉  
  5. ///〈 returns 〉〈 /returns 〉  
  6. publicstaticstringGetChsFromHex(stringhex)  
  7. {  
  8. if(hex==null)  
  9. thrownewArgumentNullException("hex");  
  10. if(hex.Length%2!=0)  
  11. {  
  12. hex+="20";//空格  
  13. //thrownewArgumentException  
  14. ("hexisnotavalidnumber!","hex");  
  15. }  
  16. //需要將hex轉(zhuǎn)換成byte數(shù)組。  
  17. byte[]bytes=newbyte[hex.Length/2];  
  18.  
  19. for(inti=0;i〈 bytes.Length;i++)  
  20. {  
  21. try  
  22. {  
  23. //每兩個字符是一個byte。  
  24. bytes[i]=byte.Parse(hex.Substring(i*2,2),  
  25. System.Globalization.NumberStyles.HexNumber);  
  26. }  
  27. catch  
  28. {  
  29. //Rethrowanexceptionwithcustommessage.  
  30. thrownewArgumentException("  
  31. hexisnotavalidhexnumber!","hex");  
  32. }  
  33. }  
  34.  
  35. //獲得GB2312,ChineseSimplified。  
  36. System.Text.Encodingchs=System.Text.Encoding.  
  37. GetEncoding("gb2312");  
  38. returnchs.GetString(bytes);  
  39. }  
  40.  
  41. ///〈 summary 〉  
  42. ///從漢字轉(zhuǎn)換到16進(jìn)制  
  43. ///〈 /summary 〉  
  44. ///〈 paramname="s" 〉〈 /param 〉  
  45. ///〈 returns 〉〈 /returns 〉  
  46. publicstaticstringGetHexFromChs(strings)  
  47. {  
  48. if((s.Length%2)!=0)  
  49. {  
  50. s+="";//空格  
  51. //thrownewArgumentException("  
  52. sisnotvalidchinesestring!");  
  53. }  
  54.  
  55. System.Text.Encodingchs=System.Text.  
  56. Encoding.GetEncoding("gb2312");  
  57.  
  58. byte[]bytes=chs.GetBytes(s);  
  59. stringstr="";  
  60. for(inti=0;i〈 bytes.Length;i++)  
  61. {  
  62. str+=string.Format("{0:X}",bytes[i]);  
  63. }  
  64. returnstr;  
  65. }  

注:以上來轉(zhuǎn)換代碼源于網(wǎng)絡(luò),C++中轉(zhuǎn)換的代碼也可以在網(wǎng)上找到,C++與C# WebService調(diào)用經(jīng)過以上的步驟就能基本實現(xiàn)。

三大難題到此結(jié)束,其實在整個過程中還有個最大的難題,那就是人與人的交流。因為一方使用C++,一方使用C#,語言不同,各自想問題的方式也不一樣,所以需要相互理解,相互站在對方的角度想問題。多交流、多溝通才是解決問題之道。請不要抱怨C#弱智,也請不要怪C++繁瑣,語言既然存在則有他的價值。

【編輯推薦】

  1. C# WebService發(fā)布與調(diào)用淺析
  2. 簡明教程 C# Webservice實例
  3. C#中定義裝箱和拆箱詳解
  4. 淺談C#類型系統(tǒng)
  5. 三種不同的C#異常類型
責(zé)任編輯:冰荷 來源: cnblogs
相關(guān)推薦

2021-08-13 11:30:07

大數(shù)據(jù)數(shù)據(jù)分析據(jù)中心

2012-04-25 15:57:57

Android

2011-07-25 10:42:47

2018-07-20 14:41:15

數(shù)據(jù)中心遷移管理運維

2009-10-29 09:32:51

寬帶接入網(wǎng)

2009-08-06 17:57:14

C# webServiC# WebServi

2009-08-11 14:26:56

C#動態(tài)調(diào)用WebSe

2015-07-09 10:44:48

C#WebService

2021-03-10 11:11:44

混合云IT云數(shù)據(jù)

2021-03-01 19:20:32

多云IT架構(gòu)

2018-04-25 15:50:50

2010-05-28 14:38:36

2012-05-21 09:27:53

2018-10-31 11:17:55

程序員女朋友面試

2020-09-04 15:07:54

網(wǎng)絡(luò)威脅情報CTI網(wǎng)絡(luò)攻擊

2010-12-22 17:10:34

2012-04-11 11:36:38

庫克

2010-06-22 09:43:25

數(shù)據(jù)中心的集中化管理

2022-03-01 14:12:22

區(qū)塊鏈技術(shù)安全

2013-01-21 10:46:34

公有云IaaS云計算
點贊
收藏

51CTO技術(shù)棧公眾號