在序列化'System.Data.Entity.DynamicProxies类型的对象时检测到循环引用
本文关键字:对象 检测 引用 循环 类型 DynamicProxies 序列化 System Entity Data | 更新日期: 2023-09-27 18:17:03
我有一个包含类顺序的模型在这个动作中,我从类顺序创建对象并为它填充数据,然后序列化我的对象,但抛出异常
在序列化类型为"system . data . entity . dynamicagents . order_5247e51e921c7e989617cba5719815085c1a2851ab5d00e28ec0be368d8ecd38"的对象时检测到循环引用。
我使用MVC 4和linq
my controller action
public ActionResult Posters(Order Obj)
{
Obj = new Order();
//fill data of object Obj
Session.Add("ObjOrder", Obj);
String serializedResult = new JavaScriptSerializer().Serialize((Order)Session["ObjOrder"]);
ViewBag.Order = serializedResult;
serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
serializedResult = serializer.Serialize(page_OrderBostrat);
ViewBag.BoxNum = serializedResult;
var con = new { ViewBag.BoxNum, ViewBag.Order };
page_OrderBostrat++;
return Json(con, JsonRequestBehavior.AllowGet);
}
类序
namespace MVCProject.Models
{
using System;
using System.Collections.Generic;
public partial class Order
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Order()
{
this.IllustrativeFiles = new HashSet<IllustrativeFile>();
this.Links = new HashSet<Link>();
this.LogoColors = new HashSet<LogoColor>();
this.LogoFiles = new HashSet<LogoFile>();
this.ModelFiles = new HashSet<ModelFile>();
this.Other = new HashSet<Other>();
this.TatbeqatModelsImages = new HashSet<TatbeqatModelsImage>();
this.ComputerPrograms = new HashSet<ComputerProgram>();
this.InfographicModels = new HashSet<InfographicModel>();
this.LogoModels = new HashSet<LogoModel>();
this.PaintModels = new HashSet<PaintModel>();
this.PosterModels = new HashSet<PosterModel>();
this.PropagandaModels = new HashSet<PropagandaModel>();
this.PublicationsModelsSizes = new HashSet<PublicationsModelsSize>();
this.ResponsiveDesigns = new HashSet<ResponsiveDesign>();
this.Structurals = new HashSet<Structural>();
}
public int Id { get; set; }
public string Name { get; set; }
public int TypeId { get; set; }
public string Details { get; set; }
public decimal Height { get; set; }
public decimal Width { get; set; }
public string MainColor { get; set; }
public string SecondColor { get; set; }
public string ThirdColor { get; set; }
public int PaintTypeId { get; set; }
public int Language { get; set; }
public string LanguageName { get; set; }
public int Pages { get; set; }
public int DesignType { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public string Country { get; set; }
public string City { get; set; }
public string Email { get; set; }
public string Mobile { get; set; }
public string Skype { get; set; }
public string Comment { get; set; }
public System.DateTime DateAdd { get; set; }
public bool Active { get; set; }
public bool Seen { get; set; }
public string IpAddress { get; set; }
public string IpCountry { get; set; }
public Nullable<bool> IsResponsiveDesign { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<IllustrativeFile> IllustrativeFiles { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Link> Links { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LogoColor> LogoColors { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LogoFile> LogoFiles { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ModelFile> ModelFiles { get; set; }
public virtual OrderType OrderType { get; set; }
public virtual PaintType PaintType { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Other> Other { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TatbeqatModelsImage> TatbeqatModelsImages { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ComputerProgram> ComputerPrograms { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<InfographicModel> InfographicModels { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<LogoModel> LogoModels { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PaintModel> PaintModels { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PosterModel> PosterModels { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PropagandaModel> PropagandaModels { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PublicationsModelsSize> PublicationsModelsSizes { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ResponsiveDesign> ResponsiveDesigns { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Structural> Structurals { get; set; }
}
}
如何解决这个问题…
在Order
类的许多属性中发现了一个对象,它本身引用了同一个Order
对象,可能在对象图的更深层次上。这很可能发生在virtual
导航属性中。为了简化,想象一个Order
和一个Customer
:
class Order
{
// properties describing the order
// and the customer who placed the order...
public virtual Customer Customer { get; set; }
}
class Customer
{
// properties describing the customer
// and the customer's orders...
public virtual ICollection<Order> Orders { get; set; }
}
如何序列化?为了序列化Order
,你还需要序列化它的Customer
属性,为了序列化这个属性,你还需要序列化它的Orders
属性,为了序列化它们,你还需要序列化它们的Customer
属性,以此类推。
你将不得不更仔细地绘制你的对象图,并使用一些属性来告诉序列化器要忽略什么。在上面的简化示例中,我可能会忽略Orders
属性,因为我实际上只关心聚合根Order
及其Customer
:
[JsonIgnore]
public virtual ICollection<Order> Orders { get; set; }
根据您正在使用的库,可能有多种序列化属性可供选择。我相信JsonIgnore
是JSON的一部分。网络图书馆。但无论您使用什么,这里的要点是在序列化对象时显式地告诉序列化包含/排除什么,以避免无限递归。
Json解析器必须循环反序列化对象的每个属性。其中一个属性是包含对初始对象的引用的对象。
如果你的实体有指向其他实体的导航属性,并且可以从这些实体导航回来,那么你就有了一个循环引用。它将反序列化对象,导航到第二个对象并反序列化它,然后找到指向原始对象的导航并反序列化它,以此类推。这是一个无限循环。
您需要告诉反序列化器忽略有循环引用的字段,使用注释[JsonIgnore]
我想在已经提供的答案之上添加一个。
我在几个场景中遇到过这个看似容易解决的问题。一个是在提供Web API时,另一个是在尝试使用jQuery Ajax时(我当时正在尝试从数据库中获取实体,并在Bootstrap模式中设置其值)。
我用AutoMapper解决了这个问题。我从导致递归的实体中创建了一个DTO(数据传输对象),而没有添加附加的集合。AutoMapper(一个基于约定的对象-对象映射器)允许我只选择我需要的字段,避免任何有问题的字段。