最近有个同事在搞一个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>将加工好的数据包装起来,这样就可以直接调用服务端的方法。

本文链接

arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()