Ef 4.1 - Code First - JSON Circular Reference Serialization Error

EF 4.1 - Code First - JSON Circular Reference Serialization Error

You could try to remove the virtual keyword from all navigation properties to disable lazy loading and proxy creation and then use eager loading instead to load the required object graph explicitely:

public ActionResult GetAll()
{
return Json(ppEFContext.Orders
.Include(o => o.Patient)
.Include(o => o.Patient.PatientAddress)
.Include(o => o.CertificationPeriod)
.Include(o => o.Agency)
.Include(o => o.Agency.Address)
.Include(o => o.PrimaryDiagnosis)
.Include(o => o.ApprovalStatus)
.Include(o => o.Approver)
.Include(o => o.Submitter),
JsonRequestBehavior.AllowGet);
}

Referring to your previous post it looks like your application isn't relying on lazy loading anyway because you introduced there the virtual properties to load the object graph lazily, possibly causing now the serialization trouble.

Edit

It's not necessary to remove the virtual keyword from the navigation properties (which would make lazy loading completely impossible for the model). It's enough to disable proxy creation (which disables lazy loading as well) for the specific circumstances where proxies are disturbing, like serialization:

ppEFContext.Configuration.ProxyCreationEnabled = false;

This disables proxy creation only for the specific context instance ppEFContext.

(I've just seen, @WillC already mentioned it here. Upvote for this edit please to his answer.)

Circular reference in EF Code-First

The fluent API for modeling these two one-to-many associations is:

modelBuilder.Entity<Player>()
.HasOptional(p => p.Address)
.WithMany()
.HasForeignKey(p => p.AddressId);
modelBuilder.Entity<Location>()
.HasRequired(l => l.Owner)
.WithMany()
.HasForeignKey(l => l.OwnerId);

As you see, the WithMany() method can be used without parameters to indicate that the association doesn't have a collection navigation property on the other end. I think that's an omission in the documentation page you refer to.

Circular reference detected exception while serializing object to JSON

Your POCO entities are perfectly serializable. Your problem is that the dynamic proxies the EF runtime creates for you are usually not. You can set the context.Configuration.ProxyCreationEnabled to false but then you lose lazy loading. My strong recommendation to you is to use Json.NET which supports serialization for EF entities:

ADO.NET Entity Framework support accidently added to Json.NET

Popular high-performance JSON framework for .NET

Circular Reference exception when serializing database object

If you are using Code first then avoid using virtual keyword from User property in Playlist Model and Playlist from Song model.
Because Playlist auto load your User model and thus again your Playlist is by User and loop goes on.

Entity to json error - A circular reference was detected while serializing an object of type

Its because it is trying to load child objects and it may be creating some circular loop that will never ending( a=>b, b=>c, c=>d, d=>a)

you can turn it off only for that particular moment as following.So dbcontext will not load customers child objects unless Include method is called on your object

  db.Configuration.ProxyCreationEnabled = false;
User ma = db.user.First(x => x.u_id == id);
return Json(ma, JsonRequestBehavior.AllowGet);

A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies'

You PlacesVM view model contains a property that is typeof Place which in turn contains a property which is typeof AspNetUser which in turn contains a property which is typeof Collection<Place>.

When the Json.Encode() method serializes you model, it serializes Place which then serializes AspNetUser which then serializes each Place which throws the error, because if allowed to continue, it would serialize each AspNetUser and so on and so on until the system ran out of memory.

Change you view model to include only those property that you need in the view - refer What is ViewModel in MVC?. Note that a view model should not generally contain properties which are data models, particularly when you editing data in a view. Instead, copy the properties from Place into PlaceVM that you need to edit, except AspNetUser, and if you need to display some properties of AspNetUser, then just include additional properties for then, for example public string UserName { get; set; }.

Side note: Your current view model does not contain a default (parameterless) constructor so the DefaultModelBinder will throw an exception when you submit.

Entity framework - Avoid circular Relationship in serialization

Note, your code should look like this:

using (cduContext db = new cduContext())
{
// get the user
string encryptedPassword = Encryption.Encrypt(password);
var user = from u in db.Users
where u.UserName.Equals(login) &&
u.Password.Equals(encryptedPassword)
select u;
// Include the users profile
return user.Include("Profile").FirstOrDefault();
}

In your code, you were throwing away the first query by overwriting it with the second. And there was no valid reason to create a blank user.

To address your problem, you're going to have make a decision on what you don't want to serialize. In your case, you probably don't want to serialize Profile.Users

You don't mention what serializer you're using. I'm assuming you're using the DataContract serializer?

EDIT:

You would mark your Profile.Users object with the [IgnoreDataMember] Attribute.

Best solution for EF 4.1 + MVC + JSON circular reference exception?

Use a view model and AutoMapper to map between your domain models and the view model which you will be sending to the view. This way you have total control over what properties are sent to the view which as a consequence reduces the amount of data sent between the server and the client. Also because now you are using view models your code is more resilient to modifications in your domain entities. If you modify them, only the mapping layer will be affected and thus you will not ever need to touch to your controllers or views.

So my advice is to download AutoMapper, read the documentation and start using it. It's a life changer, believe me.

How to Get Full Object with Code First Entity Framework 4.1

Add the virtual keyword before your related entities:

public class Order
{
public int Id { get; set; }

public virtual Patient Patient { get; set; }

public virtual CertificationPeriod CertificationPeriod { get; set; }

public virtual Agency Agency { get; set; }

public virtual Diagnosis PrimaryDiagnosis { get; set; }

public virtual OrderApprovalStatus ApprovalStatus { get; set; }

public virtual User Approver { get; set; }

public virtual User Submitter { get; set; }

public DateTime ApprovalDate { get; set; }

public DateTime SubmittedDate { get; set; }
public Boolean IsDeprecated { get; set; }
}

You might end up with a A circular reference was detected while serializing an object... error if your objects have references of each other. In that case, you will need to create a ViewModel or something similar to overcome this problem. Or use LINQ to project an anonymous object.



Related Topics



Leave a reply



Submit