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

时间:2016-06-05 11:53:57

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

我有一个Asp.NET MVC项目,数据库优先。 我在放置控制器中有创建操作。在动作方法中,我得到了这样的数据:

(initialized ? identity : initialize) (callback_with_very_long_name)

我的地方视图模型如下所示:

// 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);
}

我的地方模特:

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

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

AspNetUser:

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; }
    }

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

我尝试过以下方法:

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; }
    }

但我收到了这个错误:

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

我已经在SO上检查了以下链接,但没有设法解决我的问题:

1 个答案:

答案 0 :(得分:2)

PlacesVM视图模型包含一个Place类型的属性,该属性又包含一个AspNetUser类型的属性,该属性又包含Collection<Place>类型的属性

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

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

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