Максимальная квота длины массива

Я пишу небольшое приложение WCF/WPF для изменения размера изображений, но WCF очень огорчает меня, когда я пытаюсь отправить клиенту изображение размером 28 КБ. Служба отлично работает, когда я отправляю картинки меньшего размера. Я сразу предположил, что это была проблема с конфигурацией, и я просмотрел сообщения, касающиеся свойства MaxArrayLength в моей конфигурации привязки. Я увеличил ограничения на эти параметры на клиенте и сервере до максимального значения 2147483647, но все равно получаю следующую ошибку:

Программа форматирования вызвала исключение при попытке десериализации сообщения: при попытке десериализации параметра http://mywebsite.com/services/servicecontracts/2009/01:OriginalImage произошла ошибка. Сообщение InnerException было "Произошла ошибка десериализации объекта типа System.Drawing.Image. Максимальная квота длины массива (16384) была превышена при чтении данных XML. Эту квоту можно увеличить, изменив свойство MaxArrayLength объекта XmlDictionaryReaderQuotas, используемого при создании средства чтения XML.'. Пожалуйста, смотрите InnerException для более подробной информации.

Я сделал мои настройки клиента и сервера одинаковыми, и они выглядят следующим образом: Сервер:

<system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_ImageResizerServiceContract" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
                maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="32"
                              maxStringContentLength="2147483647"
                              maxArrayLength="2147483647"
                              maxBytesPerRead="2147483647"
                              maxNameTableCharCount="2147483647" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="ServiceBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service name="LogoResizer.WCF.ServiceTypes.ImageResizerService" behaviorConfiguration="ServiceBehavior">
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:900/mex/"/>
                    <add baseAddress="net.tcp://localhost:9000/" />
                </baseAddresses>
            </host>
            <endpoint binding="netTcpBinding" contract="LogoResizer.WCF.ServiceContracts.IImageResizerService" />
            <endpoint  address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>

и мой клиентский конфиг выглядит так:

 <system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_ImageResizerServiceContract" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
                maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="32" 
                              maxStringContentLength="2147483647"
                              maxArrayLength="2147483647" 
                              maxBytesPerRead="2147483647" 
                              maxNameTableCharCount="2147483647" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>
        </netTcpBinding>
    </bindings>
    <client>
        <endpoint address="net.tcp://localhost:9000/" binding="netTcpBinding"
            bindingConfiguration="NetTcpBinding_ImageResizerServiceContract"
            contract="ImageResizerService.ImageResizerServiceContract"
            name="NetTcpBinding_ImageResizerServiceContract">
            <identity>
                <userPrincipalName value="me@domain.com" />
            </identity>
        </endpoint>
    </client>
</system.serviceModel>

Кажется, независимо от того, что я установил эти значения, я все равно получаю сообщение об ошибке, в котором говорится, что wcf не может сериализовать мой файл, потому что он больше 16384. Есть идеи?

Обновление: адрес электронной почты в теге userPrincipalName был изменен для моей конфиденциальности

4 ответа

Решение

Мой Плохой - я забыл применить свою конфигурацию привязки к моей конечной точке в моей конфигурации на стороне сервера. Конфигурация сервера должна выглядеть так:

<system.serviceModel>
    <bindings>
        <netTcpBinding>
            <binding name="NetTcpBinding_ImageResizerServiceContract" closeTimeout="00:01:00"
                openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
                hostNameComparisonMode="StrongWildcard" listenBacklog="10"
                maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="10"
                maxReceivedMessageSize="2147483647">
                <readerQuotas maxDepth="2147483647"
                              maxStringContentLength="2147483647"
                              maxArrayLength="2147483647"
                              maxBytesPerRead="2147483647"
                              maxNameTableCharCount="2147483647" />
                <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
                <security mode="Transport">
                    <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
                    <message clientCredentialType="Windows" />
                </security>
            </binding>

        </netTcpBinding>
    </bindings>
    <behaviors>
        <serviceBehaviors>
            <behavior name="ServiceBehavior">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service name="LogoResizer.WCF.ServiceTypes.ImageResizerService" behaviorConfiguration="ServiceBehavior">
            <host>
                <baseAddresses>
                    <add baseAddress="http://localhost:900/mex/"/>
                    <add baseAddress="net.tcp://localhost:9000/" />
                </baseAddresses>
            </host>
            <endpoint bindingConfiguration="NetTcpBinding_ImageResizerServiceContract" binding="netTcpBinding" contract="LogoResizer.WCF.ServiceContracts.IImageResizerService" />
            <endpoint  address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        </service>
    </services>
</system.serviceModel>

Обратите внимание, что bindingConfiguration="NetTcpBinding_ImageResizerServiceContract" был добавлен к конечной точке netTcp. Мое приложение теперь работает с большими изображениями. Милая.

Пожалуйста, добавьте <readerQuotas> в обязательном порядке.

Это основная проблема при загрузке и загрузке байта [], она решила мою проблему.

<basicHttpBinding>
    <binding name="ServicesBinding" transferMode="Streamed" maxBufferSize="200000000"
        maxReceivedMessageSize="200000000" messageEncoding="Text"  
        receiveTimeout="00:10:00">
        <readerQuotas maxDepth="2147483647"
            maxStringContentLength="2147483647"
            maxArrayLength="2147483647"
            maxBytesPerRead="2147483647"
            maxNameTableCharCount="2147483647" />
    </binding>
</basicHttpBinding>

Я использовал Microsoft SDK SvcConfigEditor. У вас есть это, если вы используете Visual Studio (которая имеет свою собственную версию). Это также бесплатная загрузка.

На вашем жестком диске (проверьте и Program Files, и Program Files (x86)):

C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ NETFX 4.0 Tools \ SvcConfigEditor.exe

C: \ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Bin \ NETFX 4.0 Tools \ SvcConfigEditor.exe

Если у вас есть несколько установок Microsoft SDK, то какая версия вы используете, будет зависеть от того, под какой версией.NET вы разрабатываете. Инструмент выдаст ошибку, чтобы вы знали, что вы пытались открыть файл.dll под неправильной версией.

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

Мне не хватало конфигурации на стороне сервера. Я должен был сделать две вещи:

  1. Поместите конечную точку в мой серверный конфиг, настроенный с помощью SvcConfigEditor
  2. Не забудьте установить MaxArrayLength в инструменте SvcConfigEditor

Кроме того, ASP.NET требовательно подходил к этому значению, поэтому вы можете попробовать упростить привязку конфигурации и отключить ее:

  <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />

Он работает, ранее показывал ссылку на net.tcp://myservice.com/Ac_Service.svc/mex при просмотре сервиса wcf, но теперь это http://myservice.com/Ac_Service.svc?wsdl

Будет ли это работать в будущем, без каких-либо проблем.

Другие вопросы по тегам