在序列化'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; }
   }
 }

如何解决这个问题…

在序列化'System.Data.Entity.DynamicProxies类型的对象时检测到循环引用

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(一个基于约定的对象-对象映射器)允许我只选择我需要的字段,避免任何有问题的字段。