Saturday, October 06, 2012

Error: The underlying connection was closed

This is one of the most interesting error you may come across specially when using WCF Services. It will give you no detail, just go figure out - The underlying connection was closed: The connection was closed unexpectedly. So what to do? Most likely you have dataset size issue which is going back and forth between different tiers. For the security and performance reasons you should always limit the size. But if you are required to pass big chunk of data, you have to change the size to it’s maximum. So how do we do it?

 

You have to change the configuration on both side (client and service).

 

On the WCF Service side: ensure that you have

 

<dataContractSerializer maxItemsInObjectGraph="2147483647" />

 

2GB is the maximum size you can send data at once using WCF Service, so please be careful, you can adjust to a lower value as needed

 

<behaviors>
       <serviceBehaviors>
          <behavior name="serviceBehavior_Name">             
            <dataContractSerializer maxItemsInObjectGraph="2147483647" />
          </behavior>
       </serviceBehaviors>
</behaviors>

On the Client Side: Make sure that Binding and behavior info are set correctly

e.g. Binding

<binding name="wsHttpEndpoint_ITestService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
         <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647"/>
         <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/>
         <security mode="Message">
           <transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
           <message clientCredentialType="Windows" negotiateServiceCredential="true" establishSecurityContext="true"/>
         </security>
</binding>

Client Behavior

<behaviors>
     <endpointBehaviors>
       <behavior name="endpointBehavior_Common">
         <dataContractSerializer maxItemsInObjectGraph="2147483647" />
       </behavior>
     </endpointBehaviors>
   </behaviors>

Finally, Client where you refer the actual service

<client>
    <endpoint address="http://www.test.com/TestService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpoint_ITestService" contract="TestService.ITestService" name="wsHttpEndpoint_ITestService"  behaviorConfiguration="endpointBehavior_Common" />            
</client>

This should fix the above problem.

No comments: