Search code examples
c#wcfentity-framework-4clientcommunicationexception

WCF Trying to get a collection crashes the client


I've been playing around with WCF in conjunction with EF and have ran into a problem sending collections.

I'm working with a playground composed of 2 solutions, just the bare minimum I need to communicate over the line. Sending strings between the two works fine, adding a record in the database via the client works fine too. However, my service exposes the following contract:

[OperationContract]
IEnumerable<Company> GetAllCompanies();

Implemented in my service like:

public IEnumerable<Company> GetAllCompanies()
{
    using (var ctx = new InleerAppContext())
    {
        return ctx.Company.ToList();
    }
}

Nothing out of the ordinary and since sending objects seemed to work fine I would've expected this to work too. However, when calling GetAllCompanies() from my client:

var result2 = service.GetAllCompanies();
foreach (Company c in result2)
{
    Console.WriteLine(c.Name);
}

A CommunicationException get thrown:

An error occurred while receiving the HTTP response to http://localhost:8080/. 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.

With some more information:

at System.Net.HttpWebRequest.GetResponse()
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelRequest.WaitForReply(TimeSpan timeout)

I already changed the timeout to 30 minutes, on both the client and server by using a custom binding configuration (which is a basicHttpBinding on both sides):

<bindings>
  <basicHttpBinding>
    <binding name="longTimeoutBasicHttpBinding"
             receiveTimeout="00:30:00" 
             sendTimeout="00:30:00">          
    </binding>
  </basicHttpBinding> 
</bindings>

What am I missing here?


Solution

  • You most probably have a problem with circular reference. When WCF tries to serialize your Company instance it touch every property and so it triggers lazy loading of related entity and serializes it as well but if the entity has backward navigation property it will follow it and serialize the company again => the serializer is in infinite loop.

    There are only two ways to solve that:

    • Turn off lazy loading (or whole proxy creation) - use ctx.ContextOptions. Also don't load relation with Include
    • Remove / solve circular dependency - this is necessary if you want to serialize relations as well