【问题标题】:A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies'序列化“System.Data.Entity.DynamicProxies”类型的对象时检测到循环引用
【发布时间】:2016-06-05 11:53:57
【问题描述】:

我有一个 Asp.NET MVC 项目,首先是数据库。 我在 Place 控制器中有一个 Create 动作。在操作方法中,我得到这样的数据:

// GET: /Place/Create
[Authorize]
public ActionResult Create()
{
    string userId = User.Identity.GetUserId();
    var places = db.Places.Where(p => p.UserId == userId);

    var placesVM = new PlacesVM(places);

    ViewBag.UserId = new SelectList(db.AspNetUsers, "Id", "UserName");
    return View(placesVM);
}

我的 Place 视图模型如下所示:

public class PlacesVM
{
    public IQueryable<Place> Places { get; set; }
    public Place Place { get; set; }

    public PlacesVM(IQueryable<Place> places)
    {
        Places = places;
        Place = new Place();
    }
}

我的地方模型:

public partial class Place
    {
        public string Id { get; set; }
        public string UserId { get; set; }
        //TODO: Validare cordonate
        public decimal X { get; set; }
        public decimal Y { get; set; }

        [Display(Name = "Title")]
        [Required]
        [StringLength(250, MinimumLength = 5)]
        public string Titlu { get; set; }

        [Display(Name = "Description")]
        [Required]
        [StringLength(500, MinimumLength = 10)]
        public string Descriere { get; set; }

        [Required]
        [Range(0, 1)]
        public byte Public { get; set; }

        public virtual AspNetUser AspNetUser { get; set; }
    }

AspNet 用户:

public partial class AspNetUser
    {
        public AspNetUser()
        {
            this.AspNetUserClaims = new HashSet<AspNetUserClaim>();
            this.AspNetUserLogins = new HashSet<AspNetUserLogin>();
            this.Places = new HashSet<Place>();
            this.UserComments = new HashSet<UserComment>();
            this.AspNetRoles = new HashSet<AspNetRole>();
        }

        public string Id { get; set; }
        public string UserName { get; set; }
        public string PasswordHash { get; set; }
        public string SecurityStamp { get; set; }
        public string Discriminator { get; set; }

        public virtual ICollection<AspNetUserClaim> AspNetUserClaims { get; set; }
        public virtual ICollection<AspNetUserLogin> AspNetUserLogins { get; set; }
        public virtual ICollection<Place> Places { get; set; }
        public virtual ICollection<UserComment> UserComments { get; set; }
        public virtual ICollection<AspNetRole> AspNetRoles { get; set; }
    }

现在我想在页面的 javascript 部分使用 Model.Places proprietes。我该怎么做?

我尝试了以下方法:

<script>
    var model = '@Html.Raw(Json.Encode(Model))';
</script>

但是我收到了这个错误:

{"A circular reference was detected while serializing an object of type 'System.Data.Entity.DynamicProxies.Place_084A987E8F6FBE574A22E813FE314F2894AF728F244BDD6582AF50929FF1161D'."}

我在 SO 上查看了以下链接,但未能解决我的问题:

【问题讨论】:

  • 不相关,但如果您想将模型序列化为 javascript 对象,则需要为 var model = @Html.Raw(Json.Encode(Model));(不带引号)。
  • 您需要显示Place 的模型(它将包含一个属性,该属性是一个包含属性Place 的对象,导致循环引用)
  • AspNetUser 是否包含Place 的属性?
  • AspNetUser 包含:公共虚拟 ICollection Places { get;放; }
  • 这就是问题的原因(序列化Place 也序列化AspNetUser,然后序列化其属性Places,然后必须序列化每个Place 序列化AspNetUser 等等和依此类推——循环引用)。您将需要使用视图模型(无论如何都应该使用),其中仅包含视图中所需的属性(例如)class PlaceVM,并将您需要的属性从Place 复制到其中,AspNetUser 除外。如果您需要在视图中与 AspNetUser 相关的任何内容,只需为其添加一些属性(例如)int UserIDstring UserName`

标签: javascript json asp.net-mvc entity-framework


【解决方案1】:

您的PlacesVM 视图模型包含一个 typeof Place 的属性,该属性又包含一个 typeof AspNetUser 的属性,该属性又包含一个 typeof Collection&lt;Place&gt; 的属性。

Json.Encode() 方法序列化您的模型时,它会序列化Place,然后序列化AspNetUser,然后序列化每个抛出错误的Place,因为如果允许继续,它将序列化每个AspNetUser 和以此类推,直到系统内存不足。

更改视图模型以仅包含视图中需要的那些属性 - 请参阅 What is ViewModel in MVC?。请注意,视图模型通常不应包含属于数据模型的属性,尤其是在您在视图中编辑数据时。而是将Place 中的属性复制到PlaceVM 中您需要编辑的除AspNetUser 之外,如果您需要显示AspNetUser 的某些属性,则只需包含其他属性即可,例如public string UserName { get; set; } .

旁注:您当前的视图模型不包含默认(无参数)构造函数,因此DefaultModelBinder 将在您提交时抛出异常。

【讨论】:

    猜你喜欢
    • 2012-05-04
    • 2012-12-01
    • 1970-01-01
    • 2015-01-21
    • 2010-11-12
    • 2013-04-23
    • 2010-10-14
    相关资源
    最近更新 更多