ef4 cause Circular reference in web service
There are multiple solutions for your problem and they really depend on the type of service you are using and on the type of serialization:
- The clean approach is using DTO (data transfer objects) as @Mikael already suggested. DTO is special object which transfers exactly what you need and nothing more. You can simply create DTOs to not contain circular references and use AutoMapper to map between entities and DTOs and vice versa. +1 for @Mikael because he was the first to mentioned this.
All other approaches are based on tweeking serialization as @Haz suggested:
- WCF and
DataContractSerializer
: explicitly mark your entities withDataContract[IsReference=true]
and all properties with[DataMember]
attributes. This will allow you to use circular references. If you are using T4 template to generate entities you must modify it to add these attributes for you. - WCF and
DataContractSerializer
: implicit serialization. Mark one of related navigation properties with[IgnoreDataMember]
attribute so that property is not serialized. XmlSerializer
: mark one fo related navigation properties with[XmlIgnore]
attribute- Other serializations: mark one of related navigation properties with
[NonSerialized]
(+1 for Haz he was the first to mention this) for common serialization or[ScriptIgnore]
for some JSON related serialization.
EF6: How to avoid circular reference?
There is technically no problem to serialize the domain model directly. To avoid circular reference you cannot use lazy loading. You must keep control of the loading. To do so
- remove the virtual before each collection of your model (in code first approach)
- set lazy loading configuration to false (in database first approach)
A circular reference was detected while serializing an object of type 'SubSonic.Schema .DatabaseColumn'.
It seems that there are circular references in your object hierarchy which is not supported by the JSON serializer. Do you need all the columns? You could pick up only the properties you need in the view:
return Json(new
{
PropertyINeed1 = data.PropertyINeed1,
PropertyINeed2 = data.PropertyINeed2
});
This will make your JSON object lighter and easier to understand. If you have many properties, AutoMapper could be used to automatically map between DTO objects and View objects.
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.)
A circular reference error with ASMX with linked table
Circular reference means you have an object a
that references b
(e.g. a.B = b
) but somehow b
references a
back (like b.A = a
).
Unfortunately, it's not always that two objects point each to another. Your chain that leads to circularity can be longer (like product
points to another product
that points to department
that points back to product
).
Most of the times the root cause is that your service exposes your raw Entity Framework (or other ORM) objects that are joined using parent-child relations. Because ORM navigation properties are lazily loaded, anytime you have a product
, it has its parent (like product.Department
) but a department
has the Products
property that points back to products and one of the products is the very same product you already visited at the beginning. There's your cycle.
The solution is to create another set of classes, the DTO classes, where you maintain only one-way navigation properties. So for example, a ProductDTO
has its parent, the DepartmentDTO
but the DepartmentDTO
intentionally lacks the IEnumerable<ProductDTO> Products
property.
This way the serializer that follows your navigation properties stops at some point as there are no cycles. Your service exposes these DTO classes
[WebMethod]
public List<ProductDTO> GetData(int companyId, int custId)
{
return ProductService.GetCompanyData(companyId, custId).ToDTO();
}
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
Related Topics
Are .Net Switch Statements Hashed or Indexed
Dictionary <String,String> Map to an Object Using Automapper
Get List<> Element Position in C# Using Linq
Using String as a Lock to Do Thread Synchronization
Should You Access a Variable Within the Same Class via a Property
Field Initializer in C# Class Not Run When Deserializing
Inconsistent Accessibility Error with the Following C# Code. Why
Multicast Delegate of Type Func (With Return Value)
How to Install a Windows Font Using C#
Removing Hidden Characters from Within Strings
How to Get Full Host Name + Port Number in Application_Start of Global.Aspx
Is There an Entity Framework 7 Database-First Poco Generator
Maybe a C# Compiler Bug in Visual Studio 2015
No Itemchecked Event in a Checkedlistbox
Use "Real" Cultureinfo.Currentculture in Wpf Binding, Not Cultureinfo from Ietflanguagetag