Исключение квоты максимальной длины массива в WCF
Я пишу сервис 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 ответа
Все, что мне нужно было сделать, это изменить имя службы в файле 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>
Это не совсем ответ, так как ваша конфигурация выглядит нормально. Я думаю, что вам просто нужно проверить эти значения в коде (вывод для трассировки или отладки) на хосте службы и прокси, чтобы убедиться, что одинаковые значения в config загружены в ваши каналы.
Возможно, что достигнут другой порог, и ошибка вводит в заблуждение
Теперь я настоятельно рекомендую не использовать байтовый массив для загрузки файлов, особенно если вы используете XML. Они будут представлены в виде массивов XML, а структура будет представлять собой раздутый XML, который займет в 10 раз больше, чем исходный файл.
Я хотел бы использовать:
- WCF Streaming, который также работает с базовым связыванием и работает очень быстро
- альтернативно представьте байтовый массив как строку base64. Это займет 33% больше места, но не 1000%
ОБНОВИТЬ
Вы можете отследить имя привязки, которое использовалось для настройки службы (используйте его внутри любой из ваших операций WCF):
public int MyServiceOperation()
{
Trace.WriteLine(OperationContext.Current.EndpointDispatcher.ChannelDispatcher.BindingName)
....