Resolving XmlDictionaryReaderQuotas Error for WCF Compression using GZipEncoder with Custom Binding

To compress the WCF data transfered over the wire, Microsoft Samples contains a GZipEncoder. This encoder wraps TextMessagingEncoder applying GZip Compression on top of it (N.B. you can even wrap a Binary Encoder to enable compression on Images for instance).

But as you try to transfer a large object using GZipEncoder, you will run into the below error asking to increase maximum string length content:

Unhandled Exception: System.ServiceModel.CommunicationException: Error in deserializing body of reply message for operation ‘GetData’. The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 192, position 30. — System.Xml.XmlException: The maximum string content length quota (8192) has been exceeded while reading XML data. This quota may be increased by changing the MaxStringContentLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader.

This can look quite confusing if you are not familiar with how WCF Channel pipeline works. This error is encountered by many even if you are not using GZipEncoder outlined above. So let’s look at all solutions while using & not using GzipEncoder (below I set the limit to max allowed, though it’s not recommended) :

1) Standard Binding (No GZipEncoder)
<bindings>
      <basicHttpBinding>
        <binding>
          <readerQuotas maxStringContentLength=”2147483647″/>
        </binding>
      </basicHttpBinding>
</bindings>
//new BasicHttpBinding().ReaderQuotas.MaxStringContentLength = Int32.MaxValue
N.B. Binding is a collection of channels providing an abstract way to add readerQuotas.

2) Custom Binding (No GZipEncoder)
<bindings>
      <customBinding>
        <binding>
          <textMessageEncoding>
            <readerQuotas maxStringContentLength=”2147483647″/>
          </textMessageEncoding>
          <httpTransport />
        </binding>
      </customBinding>
</bindings>

/*
CustomBinding binding = new CustomBinding();
TextMessageEncodingBindingElement element = new TextMessageEncodingBindingElement();
element.ReaderQuotas.MaxStringContentLength = Int32.MaxValue;
binding.Elements.Add(element);

*/
N.B. For CustomBinding you need to select channels manually and for encoding channel you can specify the readerQuotas.

3) Using GZipEncoder – in this case you need to add couple of lines in GZipMessageEncodingBindingElement class (GZipMessageEncodingBindingElement.cs file). The method which you would change is below:

public override IChannelFactory BuildChannelFactory (BindingContext context)
{
if (context == null)
throw new ArgumentNullException(“context”);
context.BindingParameters.Add(this);

var property = GetProperty<XmlDictionaryReaderQuotas>(context);
property.MaxStringContentLength = 2147483647; //Int32.MaxValue
property.MaxArrayLength = 2147483647;
property.MaxBytesPerRead = 2147483647;

return context.BuildInnerChannelFactory();
}

N.B. It’s not possible to alter these parameters through configuration file while using GZipEncoder.

Hope this helps 🙂 .

10 thoughts on “Resolving XmlDictionaryReaderQuotas Error for WCF Compression using GZipEncoder with Custom Binding

  1. If we are creating binding programmatically we need to set the buffers in the following manner.

    BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
    binding.MaxReceivedMessageSize = int.MaxValue;
    binding.ReaderQuotas.MaxArrayLength = int.MaxValue;
    binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
    binding.ReaderQuotas.MaxDepth = int.MaxValue;
    binding.ReaderQuotas.MaxNameTableCharCount = int.MaxValue;
    binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;

  2. Hi,

    I added the quotas. It works fine when I get data from the WCf service, but when I send data to the WCF Service, then I still receive the MaxArrayLength exception.

    Any thoughts?

    1. You need to increase the ReaderQuotas of the custom gzip binding in your web.config….change your custombinding section to look something like this:

Leave a comment