在序列化类型为?的对象时检测到循环引用?

时间:2012-12-13 16:07:36

标签: asp.net-mvc json jquery-easyui

DB MetersTree TABLE

id       text   parentId    state

 0       root          0     open
 1    level 1          1     open
 2    level 1          1     open
 ...     

CONTROLLER

public ActionResult GetDemoTree()
{
    OsosPlus2DbEntities entity = new OsosPlus2DbEntities();
    MetersTree meterTree = entity.MetersTree.FirstOrDefault();

    return Json(meterTree, JsonRequestBehavior.AllowGet);
}

数据格式应该(例如)

[{  
    "id": 1,  
    "text": "Node 1",  
    "state": "closed",  
    "children": [{  
        "id": 11,  
        "text": "Node 11"  
    },{  
        "id": 12,  
        "text": "Node 12"  
    }]  
},{  
    "id": 2,  
    "text": "Node 2",  
    "state": "closed"  
}]  

如何创建树Json数据?如果我用它的关系编写MetersTree,我会得到标题中定义的错误。

2 个答案:

答案 0 :(得分:3)

由于EF类中的导航属性,您需要打破正在拾取的循环引用。

您可以将结果映射到这样的匿名类型,尽管这是未经测试的:

public ActionResult GetDemoTree()
{
    OsosPlus2DbEntities entity = new OsosPlus2DbEntities();
    MetersTree meterTree = entity.MetersTree.FirstOrDefault();

    var result = from x in meterTree
           select new 
            {
            x.id,
            x.text,
            x.state,
            children = x.children.Select({
                c => new {
                    c.id,
                    c.text
                })
         };

    return Json(result, JsonRequestBehavior.AllowGet);
}

答案 1 :(得分:1)

我解决了这个问题:

查看模型

public class MetersTreeViewModel
{
    public int id { get; set; }
    public string text { get; set; }
    public string state { get; set; }
    public bool @checked { get; set; }
    public string attributes { get; set; }
    public List<MetersTreeViewModel> children { get; set; }
}

<强> CONTROLLER

public ActionResult GetMetersTree()
{
    MetersTree meterTreeFromDb = entity.MetersTree.SingleOrDefault(x => x.sno == 5); //in my db this is the root.
    List<MetersTreeViewModel> metersTreeToView = buildTree(meterTreeFromDb.Children).ToList();

    return Json(metersTreeToView, JsonRequestBehavior.AllowGet);
}

BuildTree方法

private List<MetersTreeViewModel> BuildTree(IEnumerable<MetersTree> treeFromDb)
{
    List<MetersTreeViewModel> metersTreeNodes = new List<MetersTreeViewModel>();
    foreach (var node in treeFromDb)
    {
        if (node.Children.Any())
        {
            metersTreeNodes.Add(new MetersTreeViewModel
            {
                id = node.sno,
                text = node.Text,
                state = node.Text,
                children = BuildTree(node.Children)
            });
        }
        else {
            metersTreeNodes.Add(new MetersTreeViewModel
            {
                id = node.sno,
                text = node.Text,
                state = node.Text
            });
        }
    }

    return metersTreeNodes;
}

感谢所有对...感兴趣的人。