【问题标题】:WCF / Android ksoap2 / a:DeserializationFailed error and I can't change maximum string content length quota (8192)WCF / Android ksoap2 / a:DeserializationFailed 错误,我无法更改最大字符串内容长度配额 (8192)
【发布时间】:2013-06-28 13:34:30
【问题描述】:

我正在编写 WCF WebService 来处理我的 Android 项目。我有一个名为 CreateOrder 的方法,一切正常,直到我注意到如果我发送的 XML 数据文件太大,我会遇到异常:

06-28 15:23:09.894: E/Błąd wątku mainThread / Sender(6988): java.io.IOException: HTTP request failed, HTTP status: 500

然后我将我的 Android 项目库从“ksoap2-android-assembly-3.0.0-jar-with-dependencies”更改为“ksoap2-android-assembly-3.0.0-RC.4-jar-with-dependencies” " 这就是错误现在的样子:

06-28 15:18:47.124: E/Błąd wątku mainThread / Sender(6623): SoapFault - faultcode: 'a:DeserializationFailed' faultstring: '格式化程序在尝试反序列化消息时抛出异常:错误 反序列化操作“CreateOrder”的请求消息正文。这 已超出最大字符串内容长度配额 (8192),而 读取 XML 数据。这个配额可以通过改变 XmlDictionaryReaderQuotas 上的 MaxStringContentLength 属性 创建 XML 阅读器时使用的对象。第 257 行,第 38 位。 faultactor:'null' 详细信息:null

在我认识到发生了什么之后,我更改了配额的大小等。我正在处理这个问题,因为 2 天找不到解决方案。也许你们中的一些人发现我的 WCF / Config 有问题。我也过去了 Android / LogCat 的方法,但我认为这是 WCF 问题。

这是我的 WCF / App.config

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
    <httpRuntime maxRequestLength="2147483647" />
  </system.web>

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
  <system.serviceModel>
    <bindings>
      <webHttpBinding>
        <binding name="FoodsoftPortSoap11" 
                 closeTimeout="00:01:00" 
                 openTimeout="00:01:00"
                 receiveTimeout="00:10:00" 
                 sendTimeout="00:01:00" 
                 allowCookies="false"
                 bypassProxyOnLocal="false" 
                 hostNameComparisonMode="StrongWildcard"
                 maxBufferSize="2147483647" 
                 maxBufferPoolSize="2147483647" 
                 maxReceivedMessageSize="2147483647">
                 <!--messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"-->
                 <!--useDefaultWebProxy="true"-->
          <readerQuotas maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
          <security mode="None">
            <transport clientCredentialType="None" 
                       proxyCredentialType="None"
                       realm="" />
            <!--<message clientCredentialType="UserName" algorithmSuite="Default" />-->
          </security>
        </binding>
      </webHttpBinding>
      <wsHttpBinding>
        <binding name="newHTTPBinding"
                 maxBufferPoolSize="2147483647"
                 maxReceivedMessageSize="2147483647">
          <readerQuotas maxDepth="2147483647"
                        maxStringContentLength="2147483647"
                        maxArrayLength="2147483647"
                        maxBytesPerRead="2147483647"
                        maxNameTableCharCount="2147483647" />
        </binding>
      </wsHttpBinding>
    </bindings>
    <client>
      <endpoint address="basic" 
                binding="wsHttpBinding" 
                bindingConfiguration="newHTTPBinding" 
                contract="FudeoRef.FoodsoftPort"
                name="newHTTPBinding">
      </endpoint>
      <endpoint address="" 
                binding="webHttpBinding"
                bindingConfiguration="FoodsoftPortSoap11" 
                contract="FudeoRef.FoodsoftPort" 
                behaviorConfiguration="web"
                name="FoodsoftPortSoap11"  />
    </client>
    <behaviors>
      <endpointBehaviors>
        <behavior>
          <webHttp />
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

Android 线程

Thread MainThread = new Thread() {
          @Override
            public void run() {
              try {               

                Log.v("K","1 "+order);
                final String METHOD_NAME = "CreateOrder";
                final String SOAP_ACTION = "http://tempuri.org/IService1/CreateOrder";
                final SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
                Log.v("K","2 "+order);

                //request.addProperty("cXMLData", activity.getResources().getString(R.string.abc));
                //Log.v("XMLString", activity.getResources().getString(R.string.abc));
                //request.addProperty("cXMLData", TEST);
                Log.v("K","ROZMIAR "+TEST.length());
                request.addProperty("cXMLData", XMLString);
                Log.v("K","3 "+order);
                SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
                Log.v("K","4 "+order);
                envelope.dotNet=true;
                Log.v("K","5 "+order);
                Log.e("envelope",String.valueOf(envelope));
                Log.e("envelope",String.valueOf(request));
                activity.runOnUiThread (new Runnable(){ 
                      public void run() {
                         Print.MessageInform(activity, String.valueOf(request));
                      }  
                        });
                envelope.setOutputSoapObject(request);
                Log.e("K1",envelope.toString());
                Log.v("K","6 "+order);

                HttpTransportSE androidHttpTransport = new HttpTransportSE(URL);
                Log.v("K","7 "+order);

                androidHttpTransport.call(SOAP_ACTION, envelope);
                Log.e("K",envelope.toString());
                Log.v("K","8 "+order);
                // Retrieve response object 
                ResponseString = envelope.getResponse().toString();
                Log.v("K","9 "+order);
                Log.e("Przebieg synchronizacji","2. Wysłano zamówienie: "+order);
               activity.runOnUiThread (new Runnable(){ 
                  public void run() {
                      //Print.MessageInform(activity, ResponseString);
                      Parser.ParseCreateOrder(order, ResponseString, activity);
                  }  
                    });
               }
             catch (final Exception exc) {
                 activity.runOnUiThread(new Runnable(){

                        @Override
                        public void run() {
                            Log.e("Błąd wątku mainThread / Sender ", exc.toString());
                        }
                    });
            }
          }
       };

LogCat

06-28 15:24:26.744: E/Przebieg synchronizacji(6988): 1. Uruchamiam 处理 wysyłania zamówienia: 3 06-28 15:24:27.104: V/K(6988): 1 3 06-28 15:24:27.104: V/K(6988): 2 3 06-28 15:24:27.104: V/K(6988): ROZMIAR 8767 06-28 15:24:27.104: V/K(6988): 3 3 06-28 15:24:27.104: V/K(6988): 4 3 06-28 15:24:27.104: V/K(6988): 5 3 06-28 15:24:27.104: 电子/信封(6988): org.ksoap2.serialization.SoapSerializationEnvelope@42d6b658 06-28 15:24:27.104:E/信封(6988):CreateOrder{cXMLData=06-28 15:24:27.104: E/信封(6988): 06-28 15:24:27.104: 电子/信封(6988):0.0 06-28 15:24:27.104: 电子/信封(6988): 06-28 15:24:27.104: 电子/信封(6988): 1001 06-28 15:24:27.104: 电子/信封(6988):06-28 15:24:27.104:电子/信封(6988):0 ... 06-28 15:24:27.104:E/K1(6988): org.ksoap2.serialization.SoapSerializationEnvelope@42d6b658 06-28 15:24:27.104: V/K(6988): 6 3 06-28 15:24:27.104: V/K(6988): 7 3 06-28 15:24:27.144: D/dalvikvm(6988): GC_FOR_ALLOC 释放 6617K,释放 31% 15375K/22168K,暂停30ms,共32ms 06-28 15:24:27.164: E/Dodaje(6988):订购 3 06-28 15:24:27.164:E/Dodaje(6988):订购 4 06-28 15:24:27.174: E/Dodaje(6988): 订单 5 06-28 15:24:27.174: E/Dodaje(6988): order 7 06-28 15:24:28.224: I/Choreographer(6988): 跳过了 66 帧!应用程序可能在其上做太多工作 主线程。 06-28 15:24:28.364: E/Błąd wątku mainThread / 发件人(6988):java.io.IOException:HTTP 请求失败,HTTP 状态: 500

【问题讨论】:

  • 这是否是解决方案我只是建议你良好的编程习惯:你为什么不尝试 AsyncTask 来访问服务器??
  • 首先确保 wcf 客户端可以使用此服务。然后将工作 wcf 客户端的请求与 android 的请求进行比较

标签: android wcf ksoap2


【解决方案1】:

您没有在 WCF 服务配置中定义任何服务端点(您确实有客户端端点,这没有任何直接意义)。由于您没有在配置文件中明确定义端点,因此 WCF 将提供默认端点,以及基于地址方案的默认绑定。对于http://,这将是BasicHttpBinding(除非您覆盖配置文件中的协议设置)。

由于您获得的是默认绑定,因此您获得的是默认设置,并且您对配置文件中的绑定所做的任何更改都不会应用于服务,除非您 a) 将其设为该服务的默认绑定配置服务或 b) 将该配置显式分配给给定的端点。

要使配置成为给定绑定的默认配置,只需省略 name 属性:

<bindings>
  <webHttpBinding>
    <binding closeTimeout="00:01:00"
             ......

但是,这不会解决您的问题,因为您仍在使用 BasicHttpBinding(因为没有定义服务端点)。

根据您的情况,最简单的解决方案是将客户端端点更改为服务端点并分配您的绑定配置(您已经这样做了,但它们当前是客户端端点):

<services>
  <service name="<your service name>">
    <endpoint address="basic"
              binding="wsHttpBinding"
              bindingConfiguration="newHTTPBinding" 
              contract="FudeoRef.FoodsoftPort"
              name="newHTTPBinding" />
    <endpoint address="" 
              binding="webHttpBinding"
              bindingConfiguration="FoodsoftPortSoap11" 
              contract="FudeoRef.FoodsoftPort" 
              behaviorConfiguration="web"
              name="FoodsoftPortSoap11" />
  </service>
</services>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    相关资源
    最近更新 更多