在MVC5 / EF6中序列化数据模型时检测到自引用循环

时间:2014-08-12 22:02:47

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

我在使用' Json.NET '进行序列化时收到此错误“检测到自我引用循环”

我有一个预订模型

public class Book
{
    public Book()
    {
        BookPersonMap = new List<BookPersonMap>();
    }

    public int BookId { get; set; }

    public virtual ICollection<BookPersonMap> BookPersonMap { get; private set; }

    (And many other virtual Icollections)
}

这是BookPerson Mapping类:

public class BookPersonMap
{
    public int BookId { get; set; }

    public string PersonName { get; set; }

    public int PersonTypeId { get; set; }

    public virtual Book Book { get; set; } // Foreign keys

    public virtual PersonType PersonType { get; set; }
}

当我尝试序列化Book对象时,它会抛出:

"Self referencing loop detected for property 'Book' with type 'System.Data.Entity.DynamicProxies.Book_57F0FA206568374DD5A4CFF53C3B41CFDDC52DBBBA18007A896 08A96E7A783F8'. Path 'BookPersonMap[0]'."

我已尝试过一些类似帖子中建议的内容 示例:

    序列化程序设置中的
  1. PreserveReferencesHandling = PreserveReferencesHandling.Objects 返回了一个长度为300万的字符串!

  2. 串行器设置中的
  3. ReferenceLoopHandling = ReferenceLoopHandling.Ignore "An exception of type 'System.OutOfMemoryException' occurred in Newtonsoft.Json.dll but was not handled in user code"

  4. ^与“ReferenceLoopHandling.Serialize”相同的运气

  5. MaxDepth = 1 :再次无限循环。

  6. [JsonIgnore] 放在虚拟属性上是有效的,但这是一项繁琐的任务(因为有大量的FK引用)并且没有效果,因为如果我错过了一个属性,它会抛出异常。 / p>

    以上Json设置中缺少什么不起作用?

4 个答案:

答案 0 :(得分:1)

services.AddMvc().AddJsonOptions(opt => {
    opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});                                               

答案 1 :(得分:0)

我发现解决此类错误的最佳方法是使用视图模型展平您的模型。

在序列化对象之前在对象上放置一个断点并开始钻取子属性。你可能会发现你可以无限期地继续下去。

这就是序列化程序窒息的原因。

答案 2 :(得分:0)

为您的控制器创建一个构造函数,并将这行代码放在上面:     db.Configuration.ProxyCreationEnabled = false; // db是上下文的实例。

答案 3 :(得分:0)

对于asp.net mvc 5,请使用此

将以下代码添加到Application_Startglobax.asax file文件中的startup方法中。

protected void Application_Start()
    {
       ..
        GlobalConfiguration.Configuration.Formatters.JsonFormatter
                    .SerializerSettings
                    .ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
}

禁用延迟加载并 确保您的控制器不会返回

Json(..obj)

它应该返回

Ok(..obj)