Отправка объекта в службу WCF. Превышено значение MaxStringContentLength (8192 байта) при десериализации
Я создал простой веб-сервис WCF, у которого есть один метод: SubmitTicket(flightticket ft, имя пользователя строки, пароль строки)
На стороне клиента у меня есть приложение для заполнения формы (авиабилета) и отправки ее в этот недавно созданный веб-сервис. Когда этот объект полетной карты превышает 8192 байта, я получаю следующую ошибку:
"Произошла ошибка при десериализации объекта типа flightticket. Максимальная квота длины содержимого строки (8192) была превышена при чтении данных XML. Эту квоту можно увеличить, изменив свойство MaxStringContentLength объекта XmlDictionaryReaderQuotas, используемого при создании средства чтения XML".
Я провел некоторые исследования в Интернете и обнаружил, что мне нужно установить MaxStringContentLength в web.config (сервер) и app.config (клиент) на большее число. Проблема в том, что я пробовал каждую возможную комбинацию настроек в обоих конфигурационных файлах при чтении различных блогов и сайтов, но это ОСТАЛОСЬ на той же ошибке!
Я приложил свой конфигурационный код клиента и сервера (как и на данный момент, он претерпел множество изменений за день безуспешно).
Одна вещь, которую я заметил, это то, что файл configuration.svcinfo в моем клиентском приложении, кажется, всегда показывает 8192 для MaxStringContentLength, когда я обновляю ссылку на службу. Кажется, он принимает все значения по умолчанию, даже если я явно установил свойства привязки. Не уверен, что это вообще связано с моей проблемой, но стоит упомянуть.
Вот соответствующий код app.config / web.config для определения привязок конечной точки:
<<<<< КЛИЕНТ >>>>>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
</configSections>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFlightTicketWebService" 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="32" maxStringContentLength="65536" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://xx.xx.xx/xxxxxxxx.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IFlightTicketWebService"
contract="FlightTicketWebService.IFlightTicketWebService"
name="BasicHttpBinding_IFlightTicketWebService" />
</client>
</system.serviceModel>
</configuration>
<<<<< СЕРВЕР >>>>>
<?xml version="1.0"?>
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="GSH.FlightTicketWebService.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web>
<httpRuntime maxRequestLength="16384"/>
<compilation debug="true" targetFramework="4.0"/>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IFlightTicketWebService" 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="32" maxStringContentLength="65536" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None"
realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<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"/>
<services>
<service name="FlightTicketWebService">
<endpoint
name="FlightTicketWebServiceBinding"
address="http://xx.xx.xx/xxxxxxxxxxx.svc"
binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IFlightTicketWebService"
contract="IFlightTicketWebService"/>
</service>
</services>
</system.serviceModel>
<system.webServer>
2 ответа
Я думаю, что проблема заключается в том, что ваш сервис не получает свою конфигурацию, потому что вы установили имя сервиса как FlightTicketWebService, тогда как я предполагаю, что фактический тип находится в пространстве имен. Полностью квалифицируйте имя сервиса с пространством имен, и оно должно подобрать ваш конфиг
По сути, это побочный продукт функциональности конечных точек по умолчанию WCF 4, который, если он не находит подходящей конфигурации, ставит конечные точки с конфигурацией по умолчанию.
Это ответ! Я везде искал решение этой проблемы в WCF 4.0, и эта статья Ричарда Блеветта была последней частью головоломки.
Ключевые вещи, извлеченные из моего исследования:
- если служба выдает исключение, измените только файл Server Web.config; не беспокойся о клиенте
- создайте пользовательскую базовую HttpBinding:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="customBindingNameForLargeMessages">
- добавить большие значения для читателя Quota (максимально возможное, показанное здесь, настроить по вкусу)
<binding name="customBindingNameForLargeMessages"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647"
maxStringContentLength="2147483647"
maxArrayLength="2147483647"
maxBytesPerRead="2147483647"
maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
- создайте запись службы с конечной точкой, которая сопоставляется с пользовательской привязкой. Отображение происходит, когда bindingConfiguration конечной точки совпадает с именем привязки:
- Убедитесь, что имя службы и значение контракта полностью определены - используйте пространство имен и имя класса.
<system.serviceModel>
<services>
<service name="Namespace.ServiceClassName">
<endpoint
address="http://urlOfYourService"
bindingConfiguration="customBindingNameForLargeMessages"
contract="Namespace.ServiceInterfaceName"
binding="basicHttpBinding"
name="BasicHTTPEndpoint" />
</service>
</services>