【问题标题】:Json A circular reference was detected while serializing an object of typeJson 序列化类型对象时检测到循环引用
【发布时间】:2017-09-12 01:03:00
【问题描述】:

给出课程:

public class Parent
{
    public int id {get; set;}
    public int name {get; set;}

    public virtual ICollection<Child> children {get; set;}
}

[Table("Child")]
public partial class Child
{
    [Key]
    public int id {get; set;}
    public string name { get; set; }

    [NotMapped]
    public string nickName { get; set; }
}

以及控制器代码:

List<Parent> parents = parentRepository.Get();
return Json(parents); 

它可以在 LOCALHOST 上运行,但它不能在实时服务器上运行:

错误:Json 序列化类型对象时检测到循环引用

我搜索了一下,发现[ScriptIgnore]属性,所以我把模型改成

using System.Web.Script.Serialization;

public class Parent
{
    public int id {get; set;}
    public int name {get; set;}

    [ScriptIgnore]
    public virtual ICollection<Child> children {get; set;}
}

但是在live server (win2008)上也会出现同样的错误。

如何避免该错误并成功序列化父数据?

【问题讨论】:

  • Child 看起来像什么?它是否有对Parent 的反向引用?如果是这样,将ScriptIgnore 添加到反向引用可能更有意义。

标签: c# json dto


【解决方案1】:

试试下面的代码:

return Json(
    parents.Select(x => new {
        id = x.id,
        name = x.name,
        children = x.children.Select(y => new {
            // Assigment of child fields
        })
    })); 

...或者如果您只需要父属性:

return Json(
    parents.Select(x => new {
        id = x.id,
        name = x.name
    })); 

这并不是问题的真正解决方案,但它是序列化 DTO 时的常见解决方法...

【讨论】:

  • 首先感谢您的评论,如果我不需要用孩子序列化,我只需要父属性那么有没有更简单的方法?
  • 如果父母有100个属性,那我需要写(选择)所有属性吗?
  • @Expertwannabe 是的,你需要把它们全部放好......但是看,你确定你会需要所有这些吗?如果它是一些轻量级客户端使用的一些服务/DTO,最好不要传递所有信息。如果不是这样的话……
  • 我明白了,非常感谢。我希望有一些除了“选择除子项之外的所有属性”之类的方法。再次感谢!
  • 我有同样的问题,它在本地主机上工作,但在服务器(iis6,w2003 服务器)上不工作。对此决议有何想法?
【解决方案2】:

我遇到了类似的问题,同样我无法解决根本问题。我认为服务器正在使用与 localhost 不同的 dll 来通过 json.encode 转换为 json。

我确实在这里A circular reference was detected while serializing with Json.Encode 发布了问题和我的解决方案

我用 mvchelper 解决了。

【讨论】:

    【解决方案3】:

    您可以使用此代码而不使用选择扩展功能来过滤您的列。

    var list = JsonConvert.SerializeObject(Yourmodel,
        Formatting.None,
        new JsonSerializerSettings() {
            ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    });
    return list;
    

    【讨论】:

    • 如果你使用这个解决方案并且你确实有一个循环引用,你会得到一个错误。哪个错误?堆栈溢出! (刚试了一下,看到消息很开心。)
    【解决方案4】:

    我正在使用修复,因为在 MVC5 视图中使用了 Knockout。

    动作

    return Json(ModelHelper.GetJsonModel<Core_User>(viewModel));
    

    功能

       public static TEntity GetJsonModel<TEntity>(TEntity Entity) where TEntity : class
        {
            TEntity Entity_ = Activator.CreateInstance(typeof(TEntity)) as TEntity;
            foreach (var item in Entity.GetType().GetProperties())
            {
                if (item.PropertyType.ToString().IndexOf("Generic.ICollection") == -1 && item.PropertyType.ToString().IndexOf("SaymenCore.DAL.") == -1)
                    item.SetValue(Entity_, Entity.GetPropValue(item.Name));
            }
            return Entity_;  
        }
    

    【讨论】:

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