Максимальная квота длины массива - PullRequest
36 голосов
/ 21 января 2009

Я пишу небольшое приложение 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 ]

38 голосов
/ 21 января 2009

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

<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. Мое приложение теперь работает с большими изображениями. Сладкое.

6 голосов
/ 23 октября 2010

Пожалуйста, добавьте <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>
2 голосов
/ 02 марта 2011

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

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

C: \ Program Files (x86) \ Microsoft SDKs \ Windows \ v7.0A \ Bin \ NETFX 4.0 Инструменты \ SvcConfigEditor.exe

C: \ Program Files \ Microsoft SDKs \ Windows \ v7.1 \ Bin \ NETFX 4.0 Инструменты \ SvcConfigEditor.exe

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

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

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

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

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

  <serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
0 голосов
/ 23 апреля 2013

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

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

...