Json和循环引用异常

ahs*_*ele 39 asp.net-mvc serialization json circular-reference

我有一个对象,它具有对另一个对象的循环引用.鉴于这些对象之间的关系,这是正确的设计.

为了显示

Machine => Customer => Machine
Run Code Online (Sandbox Code Playgroud)

正如我所料,当我尝试使用Json来序列化机器或客户对象时,我遇到了一个问题.我不确定的是如何解决这个问题,因为我不想打破Machine和Customer对象之间的关系.解决此问题的选项有哪些?

编辑

目前我正在使用Controller基类提供的Json方法.所以我正在做的序列化基本如下:

Json(machineForm);
Run Code Online (Sandbox Code Playgroud)

Aar*_*ght 57

更新:

不要试图使用NonSerializedAttribute,因为JavaScriptSerializer显然忽略了它.

相反,使用ScriptIgnoreAttributein System.Web.Script.Serialization.

public class Machine
{
    public string Customer { get; set; }

    // Other members
    // ...
}

public class Customer
{
    [ScriptIgnore]
    public Machine Machine { get; set; }    // Parent reference?

    // Other members
    // ...
}
Run Code Online (Sandbox Code Playgroud)

这样,当你折腾MachineJson方法,它会遍历从关系MachineCustomer但不会尝试去从后CustomerMachine.

这个关系仍然存在,你的代码可以随意使用,但是JavaScriptSerializer(由Json方法使用)将忽略它.

  • 关于利用System.Web.Script.Serialization中的ScriptIgnoreAttribute的最后一点.不幸的是它位于System.Web.Extensions.dll(http://stackoverflow.com/questions/1156313/adding-system-web-script-reference-in-class-library/1156331#1156331),它需要一点点工作补充:http://forums.asp.net/p/1055356/1500247.aspx.除了讨论之外,它归结为选择删除循环引用或添加命名空间引用以忽略特定属性的序列化. (3认同)

eud*_*mos 33

尽管它的年龄,我回答这个问题,因为它是第三结果(目前)从谷歌"json.encode循环引用",虽然我并不与上面的答案(完全)同意,在使用ScriptIgnoreAttribute假定您代码中的任何地方都不会想要在某个JSON的另一个方向上遍历关系.由于一个用例,我不相信锁定你的模型.

它确实激励我使用这个简单的解决方案.

既然你在MVC视图的工作,你有产品型号和你想简单的控制器内分配模型到ViewData.Model,继续使用您的视图中的LINQ查询扁平化的数据很好地消除违规您想要的特定JSON的循环引用:

var jsonMachines = from m in machineForm
                   select new { m.X, m.Y, // other Machine properties you desire
                                Customer = new { m.Customer.Id, m.Customer.Name, // other Customer properties you desire
                              }};
return Json(jsonMachines);
Run Code Online (Sandbox Code Playgroud)

或者如果机器 - >客户关系是1 ..* - >*然后尝试:

var jsonMachines = from m in machineForm
                   select new { m.X, m.Y, // other machine properties you desire
                                Customers = new List<Customer>(
                                               (from c in m.Customers
                                                select new Customer()
                                                {
                                                   Id = c.Id,
                                                   Name = c.Name,
                                                   // Other Customer properties you desire
                                                }).Cast<Customer>())
                               };
return Json(jsonMachines);
Run Code Online (Sandbox Code Playgroud)


Tho*_*mas 10

基于txl的答案,您必须禁用延迟加载和代理创建,您可以使用常规方法来获取数据.

例:

//Retrieve Items with Json:
public JsonResult Search(string id = "")
{
    db.Configuration.LazyLoadingEnabled = false;
    db.Configuration.ProxyCreationEnabled = false;

    var res = db.Table.Where(a => a.Name.Contains(id)).Take(8);

    return Json(res, JsonRequestBehavior.AllowGet);
}
Run Code Online (Sandbox Code Playgroud)