Question

I have been developing an application for the last five months and just ran into this problem.

We are using EF5 and, similar to this question, I designed the class hierarchy to have all entity classes derived from an abstract base class to force validation interfaces to be implemented. We are also using the validation attributes in the entity classes.

Everything has worked fine until I started trying to use the entity classes in WCF Services. I am getting a bunch of serialization exceptions, and have been trying to figure out what "POCO" rule I broke in the design. This article tells me the class (obviously...) cannot be abstract, but since my classes are DERIVING from an abstract class, have I perhaps broken a rule I don't know about?

UPDATE: Here is the exception that I am struggling with:

System.Runtime.Serialization.SerializationException, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Type 'System.Data.Entity.DynamicProxies.WorkSession_63308485A9007DE087FF55AD9F246FD677863AA39AD56FEF4586AB87E21832DD' with data contract name 'WorkSession_63308485A9007DE087FF55AD9F246FD677863AA39AD56FEF4586AB87E21832DD:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.

Was it helpful?

Solution

Since your POCOs use lazy loading, you don't get actual types from the EF but rather proxies so that navigation properties are auto implemented for lazy loading.

My advice is to forget the idea of exposing domain objects from web services. I bet there will be answers trying to convince you that this is possible in this particular case with a bunch of extra spells casted. However, the safest approach is to switch your thinking to DTOs, Data Transfer Objects, a pattern where you create an extra layer of "data-only" classes which are light and safe to serialize and send over the wire.

There are a lot of great articles explaining on how to expose your data using the DTO pattern and a couple of extra supporting technologies like the AutoMapper. You will find details easily and you can come back for further answers.

OTHER TIPS

You didn't break a "POCO rule". The "dynamic proxy" mentioned in the exception is a class that is derived from your WorkSession entity, but it isn't derived in your code but dynamically at runtime. Entity Framework does this - by default - to make lazy loading and dynamic change tracking possible if you have marked your navigation properties (and maybe also scalar properties) as virtual.

You should disable dynamic proxy creation when you intend to serialize an entity with WCF. You can do this by simply setting a flag on the context before you load your entities from the database:

context.Configuration.ProxyCreationEnabled = false;

var worksessions = context.WorkSessions.....ToList();

The loaded worksessions are of the real runtime type WorkSession now, not of a dynamic proxy type and WCF shouldn't complain anymore.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top