TwitterFacebookGoogle

WCF client-proxies cannot consume values of type IEnumerable!

So, I spent a few hours spinning my wheels trying to figure out why I’ve been getting the following exception:

[SocketException (0x2746): An existing connection was forcibly closed by
the remote host]
[IOException: Unable to read data from the transport connection:
An existing connection was forcibly closed by the remote host.]
[WebException: The underlying connection was closed: An unexpected
error occurred on a receive.]
[CommunicationException: An error occurred while receiving the HTTP
response to http://myservice.mydomain.dk/MyService.svc. This could
be due to the service endpoint binding not using the HTTP protocol.
This could also be due to an HTTP request context being aborted by
the server (possibly due to the service shutting down). See server
logs for more details.]

Of the many reasons why you might see this exception, one is that the return value of a WCF service method cannot be of type System.Collections.IEnumerable or System.Collections.Generic.IEnumerable. If it is, then you’ll see the very informative and totally relevant (yes, I am being sarcastic) exception above when you try to consume the method on the client-side!

The solution of course is to change the service method definition to return an array.

Twitter Email Linkedin Digg Stumbleupon Subscribe

A case for C#’s dynamic keyword

Many developers feel, myself included, that C#’s ‘dynamic’ keyword is…well, a little too dynamic. But, recently, I faced a challenging problem which I was only able to solve through the use of the ‘dynamic’ keyword! Here goes…

In short, I had to write a method that adds a WCF behavior to a VS-generated WCF proxy class. What I wanted to do is something like the following:

public void AddCommonWcfBehavior(ICommunicationObject wcfClientProxy)
{
    ClientBase wcfClientBase = wcfClientProxy as ClientBase;
    wcfClientBase.Endpoint.Behaviors.Add(new MyCommonWcfBehavior());
}
/* Note that the method is taking in an object to type 
    'System.ServiceModel.ICommunicationObject' which is the base-level 
    interface for all WCF client proxies.
*/

However, I couldn’t do this for the simple reason that ClientBase<> is a generic class and .NET does not provide a non-generic version. Go figure! And no, for reasons that are too detailed to list here, I could not make AddCommonWcfBehavior() a generic method. I wish .NET offered a non-generic ClientBase class. But it doesn’t and thus I was stuck!

It was then that I remembered reading about the dynamic keyword not too long ago. Using the dynamic keyword, the method looks like the following (and works as expected):

public void AddCommonWcfBehavior(ICommunicationObject wcfClientProxy)
{
    dynamic wcfClientBase = wcfClientProxy;
    wcfClientBase.Endpoint.Behaviors.Add(new MyCommonWcfBehavior());
}

So the moral of the story: Keep the dynamic keyword in mind! In some cases, it may be your one and only savior!

Twitter Email Linkedin Digg Stumbleupon Subscribe

WCF over HTTPS

I have been working on a WCF web service that I finally deployed to our staging server which runs over HTTPS. Everything seemed fine. I was able to hit it and generate the WSDL. However, when I tried running the svcutil.exe on it, I got the following error:

Error: Cannot add the transport element 'httpTransport'. Another transport eleme
nt already exists in the binding 'System.ServiceModel.Configuration.HttpTranspor
tElement, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=
b77a5c561934e089'. There can only be one transport element for each binding.

Upon investigation, I realized that when deploying a WCF web service over HTTPS, you must set the ‘Security’ mode to ‘Transport.’. Below are the steps to do this:

1. Add the following inside the section:

<bindings>
  <wsHttpBinding>
     <binding name="webBinding">
       <security mode="Transport"></security>
     </binding>
  </wsHttpBinding>
</bindings>

2. Add the following attribute to the element:

bindingConfiguration="webBinding"

That should be all.

Below is a sample section:

<system.serviceModel>
  <services>
    <service name="MyWebService"
        behaviorConfiguration="ServiceBehavior">
	<!-- Service Endpoints -->
	<endpoint address="" binding="wsHttpBinding"
           bindingConfiguration="webBinding" contract="IMyWebService">
	</endpoint>
       <endpoint address="mex" binding="mexHttpBinding" 
         contract="IMetadataExchange" />
   </service>
</services>
<bindings>
  <wsHttpBinding>
     <binding name="webBinding">
       <security mode="Transport" />
     </binding>
  </wsHttpBinding>
</bindings>
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <serviceMetadata httpGetEnabled="true"/>
    </behavior>
  </serviceBehaviors>
</behaviors>
</system.serviceModel>
Twitter Email Linkedin Digg Stumbleupon Subscribe
CyberChimps