Пользовательский кодировщик сообщений в WCF с поддержкой ReaderQuotas

Нашел ответ здесь (последний пост): http://social.msdn.microsoft.com/Forums/eu/wcf/thread/f5c0ea22-1d45-484e-b2c0-e3bc9de20915

У меня есть одна последняя проблема с реализацией моего пользовательского ( TextOrMtomEncoder), который является реализацией ReaderQuotas.

Я много искал в Интернете, но не могу понять, какой последний кусок головоломки.

У меня есть класс, который содержит мои реализации "BindingElementExtensionElement" и "MessageEncodingBindingElement".

Реализация MessageEncodingBindingElement содержит переопределение для:

T GetProperty<T>(BindingContext context)

который я "позаимствовал" из стандартных реализаций.NET MessageEncoding, таких как TextMessageEncoding.

Это должна быть правильная реализация, потому что MSDN так говорит.

Конфигурация загружается нормально из web.config, я вижу, что свойства ReaderQuotas в обоих моих классах установлены правильно, но похоже, что.NET не читает конфигурацию ReaderQuotas из моей реализации MessageEncodingBindingElement.

Я предполагаю, что.NET использует метод GetProperty для загрузки конфигурации, потому что MessageVersion запрашивается через этот метод. Но проблема в том, что T никогда не равен XmlDictionaryReaderQuotas, поэтому ReaderQuotas никогда не запрашивается с начала.

Корень моего вопроса странный, кстати, я разрабатываю на Windows 7 x64 машина с IIS7.5. Размещение больших файлов (например, 100 КБ) работает на моем компьютере. Но когда я развертываю службу в Windows Server 2008 R2 (пробовал 2 разных сервера), я получаю следующую ошибку:

Средство форматирования выдало исключение при попытке десериализации сообщения: при попытке десериализации параметра http://socialproxy.infocaster.net:argument произошла ошибка. Сообщение InnerException было "Произошла ошибка десериализации объекта типа System.Object. Максимальная квота длины массива (16384) была превышена при чтении данных XML. Эту квоту можно увеличить, изменив свойство MaxArrayLength объекта XmlDictionaryReaderQuotas, используемого при создании средства чтения XML. Строка 1, позиция 1584.'. Пожалуйста, смотрите InnerException для более подробной информации.

И как я уже сказал, это работает на моей машине:-/

Кто-нибудь может сказать мне, как я могу решить это?

Спасибо заранее!

Конфигурация службы WCF:

<system.serviceModel>
    <extensions>
        <behaviorExtensions>
            <add name="wsdlExtensions" type="WCFExtras.Wsdl.WsdlExtensionsConfig, WCFExtras, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
            <add name="textOrMtomMessageBehavior" type="InfoCaster.SocialProxy.lib.TextOrMtom.TextOrMtomMessageBehavior, InfoCaster.SocialProxy" />
        </behaviorExtensions>
        <bindingElementExtensions>
            <add name="textOrMtomEncoding" type="InfoCaster.SocialProxy.lib.TextOrMtom.TextOrMtomEncodingElement, InfoCaster.SocialProxy" />
        </bindingElementExtensions>
    </extensions>
    <bindings>
        <customBinding>
            <binding name="TextOrMtomBinding">
                <textOrMtomEncoding messageVersion="Soap11">
                    <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="204800000" maxBytesPerRead="5242880" maxNameTableCharCount="5242880" />
                </textOrMtomEncoding>
                <httpTransport maxBufferSize="5242880" maxReceivedMessageSize="5242880" transferMode="Buffered" authenticationScheme="Anonymous" />
            </binding>
        </customBinding>
    </bindings>
    <services>
        <clear />
        <service name="InfoCaster.SocialProxy.SocialProxy" behaviorConfiguration="InfoCaster.SocialProxy.ISocialProxyServiceBehavior">
            <endpoint name="SocialProxyServiceEndpoint" address="" binding="customBinding" bindingConfiguration="TextOrMtomBinding" contract="InfoCaster.SocialProxy.ISocialProxy" behaviorConfiguration="InfoCaster.SocialProxy.ISocialProxyEndpointBehavior" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <clear />
            <behavior name="InfoCaster.SocialProxy.ISocialProxyServiceBehavior">
                <!-- 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>
        <endpointBehaviors>
            <clear />
            <behavior name="InfoCaster.SocialProxy.ISocialProxyEndpointBehavior">
                <textOrMtomMessageBehavior />
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
</system.serviceModel>

1 ответ

Решение

Нашел ответ здесь (последний пост): http://social.msdn.microsoft.com/Forums/eu/wcf/thread/f5c0ea22-1d45-484e-b2c0-e3bc9de20915

Хорошо, я нашел это. Вы должны передать цитаты читателя стандартным кодировщикам. К сожалению, для этого нет конструктора, поэтому вы должны установить свойство.

class TextOrMtomEncoder : MessageEncoder   {
    MessageEncoder _textEncoder;
    MessageEncoder _mtomEncoder;
    public TextOrMtomEncoder(MessageVersion messageVersion, XmlDictionaryReaderQuotas readerQuotas)
    {
      TextMessageEncodingBindingElement textEncoderBindingElement = new TextMessageEncodingBindingElement(messageVersion, Encoding.UTF8);
      MtomMessageEncodingBindingElement mtomEncoderBindingElement = new MtomMessageEncodingBindingElement(messageVersion, Encoding.UTF8);

      readerQuotas.CopyTo(mtomEncoderBindingElement.ReaderQuotas);
      readerQuotas.CopyTo(textEncoderBindingElement.ReaderQuotas);

      _mtomEncoder = mtomEncoderBindingElement.CreateMessageEncoderFactory().Encoder;
      _textEncoder = textEncoderBindingElement.CreateMessageEncoderFactory().Encoder;
    }
Другие вопросы по тегам