WCF中的最大数组长度配额异常

5
我正在编写一个WCF服务来上传文件,但是当字节数组超过16384个元素时,它会抛出异常。
异常详情如下:
“格式化程序在尝试反序列化消息时引发了异常:在读取XML数据时,请求消息的正文发生解析错误。已超出最大数组长度配额(16384)。可以通过更改创建XML读取器时使用的XmlDictionaryReaderQuotas对象上的MaxArrayLength属性来增加此配额。第1行,第22862个位置。”
客户端和服务器的配置都将最大数组长度配额设置为2147483647。
客户端配置:
<system.serviceModel>
  <bindings>
   <basicHttpBinding>
    <binding name="BasicHttpBinding_IDocumentLibraryService" 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="32" maxStringContentLength="2147483647" maxArrayLength="2147483647"
      maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
     <security mode="None">
      <transport clientCredentialType="None" proxyCredentialType="None"
       realm="" />
      <message clientCredentialType="UserName" algorithmSuite="Default" />
     </security>
    </binding>
   </basicHttpBinding>
  </bindings>
  <client>
   <endpoint address="http://localhost:50764/DocumentLibraryService.svc"
    binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IDocumentLibraryService"
    contract="DocumentLibrary.IDocumentLibraryService" name="BasicHttpBinding_IDocumentLibraryService" />
  </client>

服务器配置:

<bindings>

            <basicHttpBinding>
                <binding name="BasicHttpBinding_IDocumentLibraryService" closeTimeout="00:01:00"
                 openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                 allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                 maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                 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>
            </basicHttpBinding>
        </bindings>
        <services>

            <service name="BasicHttpBinding_IDocumentLibraryService">

                <clear />
                <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" />
                <endpoint binding="basicHttpBinding" name="DocumentLibraryService" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" address=""
                          bindingConfiguration="BasicHttpBinding_IDocumentLibraryService"/>
            </service>
        </services>
2个回答

2

我只需要在web.config文件中更改服务名称为带有命名空间的完整服务名称:

<service name="SampleNameSpace.DocumentLibraryService">

                <clear />
                <endpoint address="mex" binding="mexHttpBinding" name="mex" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" />
                <endpoint binding="basicHttpBinding" name="DocumentLibraryService" contract="Peninsula.DocumentLibrary.ServiceLayer.IDocumentLibraryService" address=""
                          bindingConfiguration="BasicHttpBinding_IDocumentLibraryService"/>
            </service>

这个乘以1000!!我白费了两天时间在墙上碰了个头,试图弄清楚我的配置有什么问题。我已经设置了所有适当的配额,但仍然出现错误。谢谢! - kelsmj

0

这并不是一个真正的答案,因为您的配置似乎没问题。我认为您只需要在服务主机代理上检查这些值(输出到跟踪或调试),以确保配置中加载了相同的值到您的通道中。

有可能是达到了另一个阈值,导致错误信息误导了您。

现在我强烈建议不要使用字节数组上传文件,特别是如果您使用XML。这些将被表示为XML数组,结构将是巨大的膨胀XML,比原始文件多10倍。

我会使用:

  • WCF Streaming,它可以与基本绑定一起使用,而且速度超快
  • 或者将字节数组表示为base64字符串。这将占用33%更多的空间,但不是1000%

更新

您可以跟踪用于配置服务的绑定名称(在任何 WCF 操作中使用它):

public int MyServiceOperation()
{
     Trace.WriteLine(OperationContext.Current.EndpointDispatcher.ChannelDispatcher.BindingName)
....

谢谢您的回复,Ali Jan。我的服务托管在IIS上。我该如何在IIS上检查这些值? - Nima M

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