最近有個同事在搞一個ios平台的程序,主要是關於OA的。因為windows平台的程序我們現在有現成的服務,所以想直接調用,后台的服務都是wcf服務,因此,首先想到了在ios上用代理的方式訪問wcf服務,可惜折騰了好幾天,也沒弄通,各種嘗試。。。gsop工具也試過,總之是代理的方式沒搞通。。好了,既然代理不行那就換個思路吧,於是乎,想到了js調用服務的方式,原理應該是一樣的,都是通過一個http請求,url的地址上寫好方法的名稱和需要傳遞的參數。不過就這樣調用wcf服務對於一個初學者來說也是一件充滿了各種草泥馬的工作啊,有木有。。。
好吧,立馬打開谷歌啊,敲上js調用wcf。。案例倒是一堆,按照各位牛人的先例,樓主在自己的項目中配置了一下,我用的是webHttpBinding
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceTypeBehaviors" >
<!-- 將下列元素添加到服務行為配置中。 -->
<serviceMetadata httpGetEnabled="true" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="Enjoy.ServicePortal.ServicePortal" >
<endpoint address="" binding="webHttpBinding" behaviorConfiguration="webHttpBehavior"
contract="Enjoy.ServicePortal.IServicePortal" />
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="webHttpBinding0" closeTimeout="10:10:10" openTimeout="10:10:10" receiveTimeout="10:10:10" sendTimeout="10:10:10" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxArrayLength="2147483647" maxStringContentLength="2147483647" maxNameTableCharCount="2147483647"
maxBytesPerRead="2147483647" maxDepth="640" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
折騰了半天,wcf真的好復雜,綁定的方式就一堆。。。測試了下,好像只有webHttpBinding這種方式才支持url后面加上方法名直接調用wcf方法,不知道說的對不對,請高手指點下。。不過我測試的結果是這樣的。
好了,配置文件調好了,wcf的契約中的方法我們也要修改下,在方法名稱的上面加上如下屬性:
[OperationContract]
[WebInvoke(BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml,ResponseFormat = WebMessageFormat.Xml, Method = "POST")]
string getByteData(
XElement bt);
通過url 的方式調用wcf服務數據的傳輸無非是兩種方式,json/xml,這里RequestFormat用的是xml格式的數據,如果采用了xml格式的數據的話,也就意味着http請求過來的數據一定要能反序列化成xml格式的數據,否則會報400請求錯誤。ok,這些屬性加上之后就可以調用我們的服務了,ios那邊的客戶端傳過來一個xml格式的字符串<DataModel><VALUE>hello wcf,我是ios客戶端!</VALUE></DataModel>,這樣的數據,經過wcf處理是沒有問題的,當比特流在網絡上傳輸到服務端的時候,wcf會自動將http請求中的數據反序列化成一個
XElement對象。因此服務的參數必須要是一個xelement對象,然后從這個對象中取到自己想用的參數;
好了,上面的方法調用wcf服務沒有問題了,已經調通了,因為我們這里是調用一個服務的門面,由這個服務的門面再去決定調用那些后台的服務,所以說這里是一個服務的接入點。ok,需求又來了,因為是移動平台上的項目,所以對網絡負載的要求也是比較高的。所以增加了壓縮和解壓的步驟,就是客戶端在調用服務的時候要先將數據壓縮,以達到減少網絡負載的目的。好了,客戶端還是剛剛的那些數據,這段xml數據經過壓縮之后通過比特流直接傳到服務端,但是結果總是報400的錯誤,提示是一個錯誤的請求,不壓縮正常,壓縮之后就出現了400的錯誤,很明顯是壓縮的之后的數據傳到服務端之后,wcf在進行反序列化的時候沒有反序列化成一個xml對象,原因是數據經過壓縮之后那些byte數據已經改變了,后來想到一個辦法,就是手工包裝壓縮后的數據,我們是這樣做的:數據還是要壓縮,壓縮完之后對這些字節再進行base64加密成文本類型的base64編碼,然后外面再用<Data></Data>將加工好的數據包裝起來,這樣就可以直接調用服務端的方法。