c WebService呼叫的三大難題

2021-05-23 15:07:41 字數 4463 閱讀 3012

c# webservice呼叫的三大難題

用c#編寫客戶端時,只需要將webservice新增到引用,就能像呼叫本地方法一樣去c# webservice呼叫。像這樣的例子也比比皆是,在這就不多講。

二、用c++實現webservice,一般會用到gsoap,具體方法見:http://www.cppblog.com/qiujian5628/archive/2008/06/19/54019.html

三、當做完了這些之後,並不代表webservice就能相互通訊了,現在我簡單列舉一下問題:

1、c#提供的webservice的url一般形如:http://localhost/webservice.asmx,但是,c++能提供的只能是:http://localhost/。c++做客戶端的時候呼叫沒有問題,但是當c#做客戶端的時候,引用c++提供的rul時,會提示沒用執行方法(http get method not implemented)。做c#開發的大部分會認為c++方提供的不是webservice,或者說提供的webservice根本就不全,都不帶.asmx檔案。做c++開發的會認為他傳輸的資料符合soap協議,靠http傳輸資料,他就是webservice。

2、當我們解決了第一步後,緊接著會發現另外乙個問題。當我們需要傳輸自定義資料型別時(在c++中稱結構體,在c#中稱實體),從c++返回的資訊中,c#無法構建出實體類。

3、當傳輸的資訊中帶有中文字元時,亂碼滿天飛。

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

web service互操作協議棧:

〈a〉、服務發現 (uddi)

〈b〉、服務描述(wsdl)

〈c〉、服務呼叫(soap)

〈d〉、訊息編碼 (xml)

〈e〉、傳輸網路層(http, tcp/ip)

其中wsdl描述webservice都有什麼方法、方法有什麼引數,什麼返回值等。soap(簡單物件訪問協議(****** object access protocol)是一種輕量的、簡單的、基於xml的協議。傳輸的資料就需要遵循這個協議。我比較簡單得認為傳輸的資料需要遵循這種格式。

借用微軟的這個圖描述下webservice的呼叫過程:

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

c++做的確實是webservice,只是他們需要給提供乙個描述文件,即.wsdl檔案。使用.net提供的wsdl.exe工具,使用命令:wsdl /o: c:/webservice.cs c:/webservice.wsdl。通過webservice.wsdl文件,生成**類,將**類寫入webservice.cs檔案中。我們拷貝這個cs檔案到專案中,將url指向http://localhost/,就能像以往那樣使用webservice了。

當出現無法傳遞複雜型別資料時,是因為使用gsoap生成的wsdl檔案與.net中生成的wsdl檔案不一樣。具體**如下:

〈!--operationresponseelement--〉 

〈elementname="result"

〉 〈complextype〉

sequence

〈elementname="a"

type="xsd:int"

minoccurs="1"

maxoccurs="1"

/〉

〈elementname="b"

type="xsd:int"

minoccurs="1"

maxoccurs="1"

/〉

〈/sequence

〈/complextype〉

〈/element〉

以上為gsoap生成的。返回實體result,

實體有兩個屬性:a,b。

〈s:elementname="testresponse"

〉 〈s:complextype〉

〈s:sequence

〈s:elementminoccurs="0"

maxoccurs="1"

name="testresult"

type="tns:result"

/〉

〈/s:sequence

〈/s:complextype〉

〈/s:element〉

〈s:complextypename="result"

〉 〈s:sequence

〈s:elementminoccurs="1"

maxoccurs="1"

name="a"

type="s:int"

/〉

〈s:elementminoccurs="1"

maxoccurs="1"

name="b"

type="s:int"

/〉

〈/s:sequence

〈/s:complextype〉

以上是.net生成的。

在下面的檔案中,多出

〈s:elementname="testresponse"

〉 〈s:complextype〉

〈s:sequence

〈s:elementminoccurs="0"

maxoccurs="1"

name="testresult"

type="tns:result"

/〉

〈/s:sequence

〈/s:complextype〉

〈/s:element〉

這個便是.net中用來構造實體的。當我們出現情況4.2時,gsoap中盡量使用.net生成的wsdl文件,生成.h檔案,以避免c++中的結構無法在c#中轉換成實體。

第三個問題,我們是通過將中文轉換成16進製制後傳輸過來,然後再轉換成中文。下面提供c#轉換的**:

///〈 summary 〉  

///從16進製制轉換成漢字

///〈 /summary 〉

///〈 paramname="hex"

〉〈 /param 〉

///〈returns〉〈 /returns

publicstaticstringgetchsfromhex(stringhex)

//需要將hex轉換成byte陣列。

bytebytes=newbyte[hex.length/2];

for(inti=0;i〈 bytes.length;i++)

catch

} //獲得gb2312,chinesesimplified。

system.text.encodingchs=system.text.encoding.

getencoding("gb2312"

);

returnchs.getstring(bytes);

} ///〈 summary 〉

///從漢字轉換到16進製制

///〈 /summary 〉

///〈 paramname="s"

〉〈 /param 〉

///〈returns〉〈 /returns

publicstaticstringgethexfromchs(strings)

system.text.encodingchs=system.text.

encoding.getencoding("gb2312"

);

bytebytes=chs.getbytes(s);

stringstr=""

;for(inti=0;i〈 bytes.length;i++)

",bytes[i]);

} returnstr;

}

注:以上來轉換**源於網路,c++中轉換的**也可以在網上找到,c++與c# webservice呼叫經過以上的步驟就能基本實現。

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

C webservice呼叫方法總結

一 webservice在cs後台程式中的呼叫 a 通過命名空間和類名直接呼叫 示例 webservice ws new webservice string s ws.helloworld b 通過新增web引用的方式呼叫,首先新增web引用,通過url指向webservice,指定web引用名,假...

C webservice 編寫 發布 呼叫

採用的工具vs2010生成工程 1.生成webservice工程 建 asp.net 空web 應用程式。2.在建好的asp.net 空web應用程式中新建項 web 服務 完成上述內容工程結構如下圖 下面主要的操作就是在webservice1.asmx.cs檔案中進行,裡面寫了幾個服務,兩個簡單服...

c WebService及其幾種呼叫方式

之前做移動端開發,都不清楚webservice是啥東東,現在接觸c 專案中有三處webservice呼叫,就不得不與其打交道了,最近碰上第三方介面位址更換,而自己專案因功能也需要增加webservice方法,所以了解了下webservice及其呼叫。webservice 我們可以理解為基於web的服...