We have a WCF client application that talks to a series of different service endpoints that all expose the same contract (basically, proxy services for disparate backends). Because we don't know the endpoint URLs until run-time, we're creating the service proxy classes dynamically like this:
public Factory()
{
this.ProxyFactory = new ChannelFactory<IProxyServiceChannel>(new BasicHttpBinding());
}
public IProxyServiceChannel GetProxy(Uri uri)
{
return this.ProxyFactory.CreateChannel(new EndpointAddress(uri));
}
This works fine, except in certain cases where the proxy is sending data that's larger than the default maximum received side of 64k. Normally, we'd just go into the configuration file and change the basic HTTP binding to allow bigger messages. With WCF 4.0 and up, we usually do this on the default (unnamed) binding, like so:
<basicHttpBinding>
<binding maxReceivedMessageSize="2147483647"
sendTimeout="00:10:00"
receiveTimeout="00:10:00">
<readerQuotas maxArrayLength="2147483647" />
</binding>
</basicHttpBinding>
Changing the default binding settings like this works for any services that we host in our application, as well as any service proxies that are created via "New Service Reference...". But for some reason, the new BasicHttpBinding()
object we're supplying to our channel factory is not picking up these settings, and is falling back to the built-in defaults.
I had assumed that these binding settings would apply to any endpoint using a BasicHttpBinding
that didn't have a more specific binding configuration specified. Is that correct? And if not, is there a way to get WCF to pick up these defaults automatically?
(NOTE: I know I can specify a name for the binding and use that in code, which is the option I'm currently pursuing, but for various technical reasons I'd prefer not to have to do that.)
new BasicHttpBinding()
will give you an instance of BasicHttpBinding
with the default values - I don't think it will read anything from the config file (even a default configuration) unless a configuration section name is passed in (which doesn't help for a default binding defined in the config file). What you want to do is create the instance and pass that in to the ChannelFactory. Something like this:
BasicHttpBinding binding = new BasicHttpBinding();
binding.MaxReceivedMessageSize = Int32.Max;
binding.SendTimeOut = new Timespan();
binding.ReceiveTimeout = new TimeSpan();
XmlDictionaryReaderQuotas quotas = new XmlDictionaryReaderQuotas();
quotas.MaxArrayLength = Int32.Max;
binding.ReaderQuotas = quotas;
this.ProxyFactory = new ChannelFactory<IProxyServiceChannel>(binding);
You could refactor the above so that you could generate via code any number of binding configurations (i.e., one method per binding configuration, for example).