WCF HTTPS And Request Entity Too Large

While working on a project yesterday I ran into a typical WCF error scenario. The requests that were being sent to the service were larger than the defaults allow. This results in a 413 error with the text ‘Request Entity Too Large’ The default of 64kb is there to prevent DoS attacks. If you want to increase the allowed request size you need to modify the binding configuration. You can find many topics on this on the internet. Below you can find a sample:

<system.serviceModel>
  <bindings>
    <basicHttpBinding>
      <binding maxReceivedMessageSize="5242880">
        <readerQuotas ... />
      </binding>
    </basicHttpBinding>
  </bindings>  
</system.serviceModel>

Unfortunately this did not solve the problem for me, I spent quite some time to resolve the issue. Turns out I also had to modify the IIS settings of the website that was hosting the WCF service. The config setting is called ‘uploadReadAheadSize’ and can be found in the serverRuntime section below system.webServer and you can use the configuration editor feature of IIS manager to modify it. Give it the same or a larger value you specify in your WCF configuration.

WCF ChannelManagement bug fix

Not really a release but I’ve just applied a bug fix that solves a null reference exception when returning null from the service you’re calling. Thanks to Jay from the Spring.NET forum for reporting and fixing the issue. I’ll clean up the code and add some more test cases the coming days. The updated code is available in the svn repository.

SVN Repository available

I’ve made availble a svn repository with the source code of the channel library for Spring.Net and my work on a Cuyahoga module for events. The last one is still pretty much a work in progress. I think I’ll be able to work on it some more later this year. There’s a lot on my todo list.

Readers have reported that the latest version of Fluent NHibernate breaks the approach which I illustrated on this blog, I’ll look into that later today. I’ll also be patching the channel library with a bug fix which someone on the Spring.Net forum was kind enough to provide. Had hoped to do that yesterday but the machine on which I was working did not have NUnit installed and Sourceforge was down. So stay tuned, this blog will get some more action in August.

Repository is located at:

Edit: Moved code to github @ https://github.com/BennyM/SpringWCFChannelManager

This week on my screen #7

WCF ChannelManagement drop 3

A new version is available, with two modes of channel pooling.

The ‘FixedPool’ mode is based on the SimplePool which you can find in the Spring.Pooling library. Meaning that at any given time there can be a maximum of x amount of channels. Where x equals the SimplePool’s size. So if the size of your pool is 5 and you request a 6th channel while the previous 5 are still busy doing their business you’ll get a blocking thread until one of the previous five is returned to the pool. This is good for when you want to limit the connectivity to your server, but don’t forget that it will block the calling thread when you request more channels than there are available.

The other pool mode is ‘VariablePool’. This is a pool that grows and shrinks depending on the load. So if you request 6 channels you’ll get 6 channels which will be available for future requests when returned to the pool. Channels which are no longer usable will be removed and new ones will be created when needed.

I spend most of the time trying to find a good away around my dependency on ChannelFactory. Since that class has a method ‘CreateChannel’ which takes no arguments and the factory can be configured using the endpoint name in your system.servicemodel section. The interface which the class implements doesn’t have this. The classes which populate a channelfactory from the app.config are marked internal and so you can’t use them.

The only solution I found that worked pretty ok was a wrapper interface which exposes the CreateChannel method, it helped me to test the code without a channelfactory instance.

I did a lot of renaming in the codebase but on the consuming end not much has changed.

A ‘SingleAction’ operating channel is still the easiest to configure.

<object id=“MyService” type=“WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager”>
	<property name=“ChannelType” expression=“T(Server.IService1, Common)/>
	<property name=“EndpointConfigurationName” value=“MyEndpoint”/>
</object>

Creating a fixed pool is one extra line.

<object id=“MyService” type=“WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager”>
	<property name=“ChannelType” expression=“T(Server.IService1, Common)/>
	<property name=“EndpointConfigurationName” value=“MyEndpoint”/>
	<property name=“ChannelManagementMode” value=“FixedPool”/>
</object>

A variable pool means just another value as ChannelManagementMode.

<object id=“MyService” type=“WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager”>
	<property name=“ChannelType” expression=“T(Server.IService1, Common)/>
	<property name=“EndpointConfigurationName” value=“MyEndpoint”/>
	<property name=“ChannelManagementMode” value=“VariablePool”/>
</object>

If you want to use your own channel manager, you can use the ProductTemplate to hook everything up. The sample below illustrates this, here the variable pool is configured via the template instead of using the ChannelManagementMode property of the FactoryObject.

<object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager">
	<property name="ChannelType" expression="T(Server.IService1, Common)"/>
	<property name="EndpointConfigurationName" value="MyEndpoint"/>
	<property name="ProductTemplate">
	<object>
		<property name="ChannelManager">
			<object type="WCFChannelManager.ChannelPoolManager&lt;Server.IService1>, Perponcher.WCFChannelManager">
				<constructor-arg value="MyEndpoint"/>
				<constructor-arg>
					<object type="WCFChannelManager.AutoSizePoolFactory, Perponcher.WCFChannelManager"/>
				</constructor-arg>
			</object>
		</property>
	</object>
	</property>
</object>

The same approach can be used to configure the channelfactory for i.e. passing credentials.

<object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager">
	<property name="ChannelType" expression="T(Server.IService1, Common)"/>
	<property name="EndpointConfigurationName" value="MyEndpoint"/>
	<property name="ChannelManagementMode" value="VariablePool"/>
	<property name="ProductTemplate">
		<object>
			<property name="ChannelManager.ChannelFactory.Credentials.UserName.UserName" value="username"/>
			<property name="ChannelManager.ChannelFactory.Credentials.UserName.Password" value="password"/>
		</object>
	</property>
</object>

That’s it for now. Future additions will include:

  • setting the pool size of a fixed sized pool via the FactoryObject, for now the default of 5 is used
  • extend or add a new pool based on the SimplePool. At the moment closed or faulted channels are not removed from that implementation, meaning that when your 5 channels are closed the pool will raise an exception.

WCFChannelManager_drop3.zip (1.16 mb)

Series:

WCF ChannelManagement drop 2

Updated version is now available, no channel pooling yet but I changed the way default values and the ProductTemplate were being handled. I’ve already used the library successfully at work in a very heavy WCF application. I found some issues with it, like when you wanted to configure the ChannelFactory in your configuration file, but these are now fixed.

Next up pooling!

WCFChannelManager_drop2.zip (1.14 mb)

Series:

First drop of ChannelManagement available.

First drop available of the ChannelManagement library. Currently only support single action channels, meaning that after executing the operation the channel is closed. I hope to add pooling the coming week.

The zip contains the source code and an example project. Not much changes in the ‘end user’ code:

static void Main(string[] args)
{
	var myService = ContextRegistry.GetContext().GetObject("MyService") as IService1;
	string value = myService.GetData(5);
	var returnValue = myService.GetDataUsingDataContract(new CompositeType() 
														 { 
														 BoolValue = false, 
														 StringValue = "Perponcher" });
	Console.ReadLine();
}
<spring>
	<context>
		<resource uri="config://spring/objects" />
	</context>
	<objects xmlns="http://www.springframework.net">
		<object id="MyService" type="WCFChannelManager.ChannelManagerFactoryObject, Perponcher.WCFChannelManager">
			<property name="ChannelType" expression="T(Server.IService1, Common)"/>
			<property name="EndpointConfigurationName" value="MyEndpoint"/>
		</object>
	</objects>
</spring>
<system.serviceModel>
	<client>
		<endpoint name="MyEndpoint" address="http://localhost:8731/Design_Time_Addresses/Server/Service1/"
			contract="Server.IService1" binding ="wsHttpBinding"/>
	</client>
</system.serviceModel>

Out and ref parameters are not yet supported.

WCFChannelManager.zip (1.17 mb)

Series: