Большой файл через сервис WCF
Подобные вопросы текут вокруг, и я посмотрел на все из них. Похоже, никто не решает мою проблему.
-- ОБНОВИТЬ: --
Я пытаюсь загрузить документ (pdf, doc или любой другой) в базу данных с помощью службы WCF. Звонок в сервис выглядит так:
using (var cw = new WCFClientWrapper<ICommonService>())
{
cw.Channel.DocumentInsert(content, filename, contentType);
}
Вот подпись для контракта:
[OperationContract]
void DocumentInsert(byte[] content, string fileName, string contentType);
Обратите внимание, что я передаю байтовый массив для содержимого, так как это то, что нужно передать для хранения вещей в БД.
- Конец обновления -
Я могу успешно загрузить небольшой файл (пара кб). Однако, когда я пытаюсь загрузить что-то большее (20 КБ), я получаю исключение:
Форматировщик выдал исключение при попытке десериализации сообщения: Ошибка в десериализации тела сообщения запроса для операции "DocumentInsert". Максимальная квота длины массива (16384) была превышена при чтении данных XML. Эту квоту можно увеличить, изменив свойство MaxArrayLength объекта XmlDictionaryReaderQuotas, используемого при создании средства чтения XML. Строка 1, позиция 31774.
Ошибка кажется очевидной... просто увеличьте MaxArrayLength. Я сделал это без какого-либо успешного результата. Ниже приведены соответствующие части из моего web.configs
Клиент:
<system.serviceModel>
<behaviors>
<endpointBehaviors>
<behavior name="SecureBehavior">
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="WSHttpBinding_Service" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="262144" messageEncoding="Text"
textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true" allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="2147483646" maxBytesPerRead="4096" maxNameTableCharCount="5242880" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://dev.svc.someurl.com/CommonService.svc"
binding="basicHttpBinding"
bindingConfiguration="WSHttpBinding_Service"
behaviorConfiguration="SecureBehavior"
contract="MyApp.Contracts.ServiceContracts.ICommonService"
name="MyApp.Contracts.ServiceContracts.ICommonService">
</endpoint>
</client>
</system.serviceModel>
Обслуживание:
<system.serviceModel>
<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>
<bindings>
<basicHttpBinding>
<binding name="MyBasicHttpBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MyApp.WCFServices.CommonService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="MyBasicHttpBinding"
contract="MyApp.Contracts.ServiceContracts.ICommonService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
<service name="MyApp.WCFServices.AccountService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="MyBasicHttpBinding"
contract="MyApp.Contracts.ServiceContracts.IAccountService">
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
</services>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Прикрепление диагностики показывает:
- Construct Service: нет ошибок / предупреждений
- Open Service: предупреждение - контекст оценки конфигурации не найден - соответствующий тег не найден. Добавлены конечные точки по умолчанию.
- Слушайте на http://dev.svc.someurl.com/CommonService.svc: нет ошибок / предупреждений
- Обработка сообщения 1: нет ошибок / предупреждений
- Действие обработки 'http://tempuri.org/ICommonService/DocumentInsert'.: исключение, которое я написал в самом начале.
Любая помощь приветствуется.
2 ответа
Я сталкивался с тем же исключением несколько месяцев назад. Для отправки / получения больших данных в / из службы WCF необходимо установить transferMode="Streamed"
, При использовании Transfermode в качестве Buffered, он фактически помещает весь файл в память перед загрузкой / загрузкой. Поэтому большой размер буфера требуется как для веб-клиента, так и для узла службы WCF. При этом потоковые передачи могут улучшить масштабируемость службы, устраняя необходимость в больших буферах памяти. Дополнительные сведения о режиме передачи см. В статье MSDN по перечислению TransferMode.
Хорошо, после дня борьбы я наконец нашел проблему. Мне просто нужно было убедиться, что имя тега в WCF web.config совпадает с пространством имен и именем службы:
<service name="ServicesImplementation.WcfServices.CommonService">
К сожалению, это было не то, что вы, ребята, увидели бы на основании информации, которую я предоставил.