Mathijs Mathijs - 3 months ago 24
JSON Question

Circular reference detected exception while serializing object to JSON

Just as mentioned in this post, I am getting a Json serialization error while serializing an Entity Framework Proxy:


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


But the difference is, I don't have a circular reference in my entities, and it only occurs in our production environment. Locally everything works fine...

My Entities:

public interface IEntity
{
Guid UniqueId { get; }
int Id { get; }
}

public class Entity : IEntity
{
public int Id { get; set; }
public Guid UniqueId { get; set; }
}

public class PurchaseOrder : Entity
{
public string Username { get; set; }
public string Company { get; set; }

public string SupplierId { get; set; }
public string SupplierName { get; set; }

public virtual ICollection<PurchaseOrderLine> Lines { get; set; }
}

public class PurchaseOrderLine : Entity
{
public string Code { get; set; }
public string Name { get; set; }
public decimal Quantity { get; set; }
}


The GetCurrent action on my PurchaseOrderController throwing the exception:

public class PurchaseOrderController : Controller
{
private readonly IUnitOfWork _unitOfWork;

public PurchaseOrderController(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}

public JsonResult GetCurrent()
{
return Json(EnsurePurchaseOrder(), JsonRequestBehavior.AllowGet);
}

private PurchaseOrder EnsurePurchaseOrder()
{
var company = RouteData.GetRequiredString("company");
var repository = _unitOfWork.GetRepository<PurchaseOrder>();

var purchaseOrder = repository
.Include(p => p.Lines)
.FirstOrDefault
(
p => p.Company == company &&
p.Username == User.Identity.Name
);

if (purchaseOrder == null)
{
purchaseOrder = repository.Create();
purchaseOrder.UniqueId = Guid.NewGuid();
purchaseOrder.Company = company;
purchaseOrder.Username = User.Identity.Name;
_unitOfWork.SaveChanges();
}

return purchaseOrder;
}
}

Answer

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