0

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?

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
duress
  • 77
  • 7
  • What happens if you return single company? Are there any navigation properties in company? Is company wrapped in dynamic proxy? Are you using lazy loading? – Ladislav Mrnka Aug 10 '11 at 12:13
  • Could you send the endpoint info for the config? – Iain Aug 10 '11 at 12:13
  • Check this link http://www.devlifestyle.net/blogs/articles/archive/2009/12/23/parsing-large-messages-in-wcf-maxitemsinobjectgraph-maxreceivedmessagesize-and-maxbuffersize.aspx – VJAI Aug 10 '11 at 12:14
  • Btw. if you setup [WCF tracing](http://msdn.microsoft.com/en-us/library/ms733025.aspx) on the service you should be able to see exception detail. – Ladislav Mrnka Aug 10 '11 at 12:14
  • @Ladislav: The same happens with a single company. There is a navigation property on it and it's wrapped in a DynamicProxy as well so it seems. LazyLoading is enabled. The problem persists when I 'Include' the navigation property. Reading up on WCF tracing atm... – duress Aug 10 '11 at 12:21
  • @Mark: Interesting link, but I don;'t think it applies to this problem, the amount of data I work with is very little. The company table contains 10 records, PhoneNumber even less. – duress Aug 10 '11 at 12:27

2 Answers2

2

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
Community
  • 1
  • 1
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Thank you again for a good answer. I learned a lot the last couple of days. GetCompany looks like: ctx.ContextOptions.ProxyCreationEnabled = false; return ctx.Company.Include("PhoneNumbers").Where(company => company.Id == id).FirstOrDefault(); Now and the data gets transmitted nicely over the line, NavigationProerty included. I can't help but feel I'm just hacking something together this way. Is this a good practice? – duress Aug 10 '11 at 13:03
  • Should I avoid PrexyCreation at all time in a WCF environment and go for DTOs? How is a DTO of added value in this setup since I can decorate properties I don't need serialized with [IgnoreDataMember] in my template? – duress Aug 10 '11 at 13:05
0

This normally happens when the seralizer is having a problem with your class. For example if company is an Entity Object and its trying to seralize one of the navigation properties, that wont work

iamkrillin
  • 6,798
  • 1
  • 24
  • 51