使用Delphi消费WCF - 最大字符串内容长度配额(8192)错误

4

我有一个WCF服务,被Delphi应用程序调用。有时候,当向服务器发送大量请求时,会出现以下错误:

---------------------------
Debugger Exception Notification
---------------------------
Project Project43.exe raised exception class ERemotableException with message 'The formatter threw an exception while trying to deserialize the message: Error in deserializing body of request message for operation 'Log'. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 58, position 140.'.
---------------------------
Break   Continue   Help   
---------------------------

我已经按照以下方式在服务器端配置了web.config:


Web.config

<?xml version="1.0" ?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>

    <bindings>
      <basicHttpBinding>
        <binding name="basicHttpBinding">
          <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
      </basicHttpBinding>
    </bindings>

    <services>
      <service name="NewServiceType">
        <clear />
        <endpoint address="http://localhost" binding="basicHttpBinding" bindingConfiguration="" contract="IRoboConsultaLog" />
      </service>
    </services>

    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

但是我一直收到这个错误。有些网友建议在客户端的app.config文件也要进行修改,但是我不知道该怎么做,因为我在使用Delphi。
我还注意到我不知道如何正确配置<endpoint>标签,也许这就是所有问题的原因。以下是我的Web服务接口和类(为了更清晰而缩减):
namespace RoboConsultaLogServer
{
    [ServiceContract]
    public interface IRoboConsultaLog
    {
        [OperationContract]
        void Log(string key, string numeroSerial, string nomeTarefa, int qtdProcessos, float uptime, float duracaoTarefa,
                 int qtdSucesso, int qtdInsucesso, int qtdCancelado, bool servico, bool notificarResponsaveis, string logProcessos);
    }
}

public class RoboConsultaLog : IRoboConsultaLog 
{
    ...
}

有人知道如何修复这个问题吗?

1个回答

3
正如您所注意到的那样,原因在于端点配置:
<endpoint address="http://localhost" binding="basicHttpBinding" bindingConfiguration="" contract="IRoboConsultaLog" />

基本上您的读者配额配置没有被使用。

绑定参数仅定义绑定类型,如果您想传递绑定配置,则必须填写BindingConfiguration参数。在您的情况下,绑定类型与配置名称相同("basicHttpBinding")仅是巧合。因此,请尝试以下操作(我已更改名称以使其更清晰):

    <bindings>
      <basicHttpBinding>
        <binding name="myBindingConfiguration">
          <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        </binding>
      </basicHttpBinding>
    </bindings>

并且

    <endpoint address="http://localhost" binding="basicHttpBinding" bindingConfiguration="myBindingConfiguration" contract="IRoboConsultaLog" />

编辑:另外,如果您发送了大量数据,也许最好将其作为文件发送,保存在会话中,然后在WCF方法中使用它。数据将在没有WCF开销的情况下发送,WCF调用将更快,使应用程序更具响应性。此外,它也不太容易出现WCF超时问题。


现在我无法启动 Web 服务。它给了我这个错误:在服务“RoboConsultaLog”实现的合同列表中找不到合同名称“IRoboConsultaLog”。 - Rafael Colucci
将命名空间添加到合同:contract="RoboConsultaLogServer.IRoboConsultaLog" - Varius
错误标题为:当在配置中将'system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled'设置为true时,端点需要指定相对地址。如果您在端点上指定了相对侦听URI,则地址可以是绝对的。要解决此问题,请为端点'http://localhost/'指定相对URI。 - Rafael Colucci
好的,现在已经搞定了。只需要设置 <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />。非常感谢!!! - Rafael Colucci
啊,我一直在比较我的配置和你的,但是没有注意到这一点。实际上,我根本没有它。好吧,我也学到了新东西。 - Varius
很好,你学到了新东西!现在我正在寻找一种不必指定终端地址的方法。我担心当我部署服务器时会忘记将其从本地主机更改... - Rafael Colucci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接