WebApi with EF code First generates an error when there is a parent child relationship

I puzzle over this problem. I found something on the Internet about this, but not a clear answer. My problem:

I have classes in the Model section of the MVC3 web application: ParentClass and ChildClass. In ParentClass, there is a List property called Children

I used EF Code First, which neatly generates a parent table and a child table for me in the database.

Now I need a REST service that returns a list or a separate ParentClass.

When I remove the Children property from ParentClass, there is no problem. But with propoerty Children there I always get an error message.

Error: "The type System.Data.Entity.DynamicProxies.ParentClass_A0EBE0D1022D01EB84B81873D49DEECC60879FC4152BB115215C3EC16FB8003A was not expected. Use the XmlInclude or SoapInclude attribute to specify types that are not known statically."}

Some codes:

Classes:

  public class ParentClass { public int ID { get; set; } public string Name {get;set;} public virtual List<ChildrenClass> Children { get; set; } } public class ChildrenClass { public int ID { get; set; } public string MyProperty { get; set; } } 

Services:

 [ServiceContract] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)] [ServiceBehavior(IncludeExceptionDetailInFaults = true)] public class MyService { static MyContext db; public MyService() { db = new MyContext(); } [WebGet(UriTemplate = "")] public List<ParentClass> GetParents() { var result = db.Parents.ToList(); return result; } 

I will not get the result when I call this service. What am I doing wrong?

+11
rest asp.net-mvc-3 entity-framework ef-code-first wcf-web-api
Nov 17 2018-11-11T00:
source share
3 answers

I had to disable ProxyCreation in the context configuration:

 [OperationContract] [WebGet(UriTemplate = "")] public List<ParentClass> GetParents() { using (DBContext context = new DBContext()) { context.Configuration.ProxyCreationEnabled = false; List<ParentClass> parents = context.Parents .Include("Children") .ToList(); return parents; } } 

It worked out fine for me.

+12
Nov 18 '11 at 16:34
source share

It seems to serialize proxy classes for your POCOs, my first recommendation would be to use proxydatacontractresolver: http://msdn.microsoft.com/en-us/library/system.data.objects.proxydatacontractresolver.aspx .

I would also work to ensure that all things are explicitly stated when loading data for sending via the web service ... i.e.

Change the parent class to

 public class ParentClass { public int ID { get; set; } public string Name {get;set;} public List<ChildrenClass> Children { get; set; } } 

Modify your content to disable lazy loading: Disable default lazy loading in Entity Framework 4

And explicitly indicate what you want to download when returning sent posting data.

 [WebGet(UriTemplate = "")] public List<ParentClass> GetParents() { var result = db.Parents.Include("Children").ToList(); return result; } 

Take a look at the following answer: Entity First Structure Code - Eager Loading does not work as expected? for more complex Include calls.

In addition, from experience, I would not return your data classes by wire, since they constitute a contract for the consumer of your web service. It is best to have a different set of classes to which you map your data values.

That way, if your data classes are changing, you don’t need to change the web service client unless it is explicitly required.

And the use of paging is important if you expect 1000 lines in parent or child classes, otherwise you can choose N + 1, see What is SELECT N + 1? .

0
Nov 18 '11 at 1:10
source share

In some situations, a simple solution is to use a wrapper class, so that all displayed properties are known types.

As a rule, you will not use ObjectContext or DbContext in your controller classes, so at an earlier level (business or service level) you can quickly transfer objects from the database to ViewModel-style objects similar to what you would do in MVC application, but instead of passing them to the view, you return them to the caller.

You may not be able to use it in all cases, but this is often a feasible compromise.

0
May 11 '12 at 17:58
source share



All Articles