Исключение квоты максимальной длины массива в WCF - PullRequest
5 голосов
/ 05 мая 2011

Я пишу сервис WCF для выгрузки файлов, но он выдает исключения, когда в байтовом массиве более 16384 элементов.

Это подробное описание исключения:

Брошено средство форматированияисключение при попытке десериализации сообщения: ошибка в десериализации тела сообщения запроса для операции «CreateDocument».Максимальная квота длины массива (16384) была превышена при чтении данных XML.Эту квоту можно увеличить, изменив свойство MaxArrayLength объекта XmlDictionaryReaderQuotas, используемого при создании средства чтения XML.Строка 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 голосов
/ 06 мая 2011

Все, что мне нужно было сделать, это изменить имя службы в файле 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>
0 голосов
/ 05 мая 2011

Это не совсем ответ, так как ваша конфигурация кажется нормальной. Я думаю, вам просто нужно проверить эти значения в коде (вывод для трассировки или отладки) на хосте службы и прокси , чтобы убедиться, что те же значения в конфигурации загружены в ваш каналы.

Возможно, достигнут другой порог и ошибка вводит в заблуждение

Теперь я настоятельно рекомендую не использовать байтовый массив для загрузки файлов , особенно если вы используете XML. Они будут представлены в виде массивов XML, а структура будет представлять собой сильно раздутый XML, который займет в 10 раз больше, чем исходный файл.

Я бы использовал:

  • WCF Streaming , который также работает с базовым связыванием и является супер быстрым
  • альтернативно представляет байтовый массив в виде строки base64 . Это займет 33% больше места, но не 1000%

UPDATE

Вы можете отследить имя привязки, которое использовалось для настройки службы (используйте его внутри любой из ваших операций WCF):

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