Search code examples
vb.netwcfwcf-binding

Unable to set ReaderQuotas for BasicHttpBinding generated in code


I have a project with requirements to generate a single executable file with no dependencies that will automate the submission of data to a WCF service based on command line parameters passed to it. As a result, I cannot configure the WCF binding and quotas in an App.config file, so I am generating a BasicHttpBinding in code to use when dimensioning the WCF client object.

However, the WCF service accepts the binary data for a relatively small Excel spreadsheet that ends up being around 30kb, so the default configuration settings for the binding's ReaderQuotas are inadequate. My attempts to increase them in code to 1MB, however, have met with failure each time I make a call to the service.

I have attempted to set the binding in the following two ways, first in the constructor itself:

Private theBinding As New BasicHttpBinding With {
    .SendTimeout = TimeSpan.FromMinutes(1),
    .OpenTimeout = TimeSpan.FromMinutes(1),
    .CloseTimeout = TimeSpan.FromMinutes(1),
    .ReceiveTimeout = TimeSpan.FromMinutes(10),
    .AllowCookies = False,
    .BypassProxyOnLocal = False,
    .HostNameComparisonMode = HostNameComparisonMode.StrongWildcard,
    .MessageEncoding = WSMessageEncoding.Text,
    .TransferMode = TransferMode.Buffered,
    .UseDefaultWebProxy = True,
    .MaxBufferSize = 1048576,
    .MaxReceivedMessageSize = 1048576,
    .ReaderQuotas = New XmlDictionaryReaderQuotas With {
        .MaxDepth = 32,
        .MaxStringContentLength = 8192,
        .MaxArrayLength = 1048576,
        .MaxBytesPerRead = 4096,
        .MaxNameTableCharCount = 16384
    }
}

And also by removing the ReaderQuotas setter in the above code and setting it to max values using System.Reflection on form load. I realize this method is more for bindings that have been created in a config file and are therefore typically immutable, but I figured it couldn't hurt to try:

theBinding.GetType.GetProperty("ReaderQuotas").SetValue(theBinding, XmlDictionaryReaderQuotas.Max, Nothing)

The WCF client is dimensioned using the final overload for WCF client constructors:

Using theClient As New WCFServiceClient(theBinding, theEndpoint)
    ...
End Using

However, I still receive the following exception when making a call to the WCF client:

System.ServiceModel.ProtocolException: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:theObject. The InnerException message was 'There was an error deserializing the object of type RootNameSpace.ObjectType. The maximum array length quota (16384) has been exceeded while reading XML data. This quota may be increased by changing the MaxArrayLength property on the XmlDictionaryReaderQuotas object used when creating the XML reader. Line 1, position 46272.'. Please see InnerException for more details.

Head is meeting desk. Could really use some guidance for what I may have missed here when it comes to properly configuring reader quotas.


Solution

  • Check your service's configuration file (if it has one) or the settings on the binding its using. It's possible the client is sending the message just fine but the service is rejecting it because it's still using the default values.