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
Populate Data Table from Data Reader
Windows Shell Extension with C#
Fastest Way to Convert Image to Byte Array
Web API How to Add a Header Parameter for All API in Swagger
Understanding .Asenumerable() in Linq to SQL
Authorization Header Is Lost on Redirect
How to Ensure a Form Displays on the "Additional" Monitor in a Dual Monitor Scenario
Differencebetween Preservereferenceshandling and Referenceloophandling in JSON.Net
Resizing an Image in ASP.NET Without Losing the Image Quality
Visual Studio Debugging "Quick Watch" Tool and Lambda Expressions
How to Convert Datatable to JSON String Using JSON.Net
Best Way to Display Decimal Without Trailing Zeroes
How to Post Data Using Httpclient
Create Bitmap from a Byte Array of Pixel Data
Observablecollection<> VS. List<>
What Are the Limitations of SQLdependency