返回 JSON 时的 C# 递归限制

本文关键字:递归 JSON 时的 返回 | 更新日期: 2023-09-27 18:34:41

我最近遇到了一个烦人的问题。我将在这里简化我的数据模型,但原理是一样的。我有一个类"用户"。在该类中,我有一个属性,它是用户拥有的对象列表。我也有这个类"对象"。因为每个"对象"都有一个所有者,所以它有一个类型为"User"的属性,该属性链接到其所有者。现在,我想做的基本上是这个

return Json(myUser,JsonRequestBehavior.AllowGet);

当我加载页面时,大约需要 30 秒,然后出现错误"超出递归限制"。

我想这是因为对象相互链接。现在我的问题是,我怎样才能告诉"Json"它不应该比 1 级对象更深以避免这种情况?

返回 JSON 时的 C# 递归限制

myUser可能是EntityFramework生成的类型。

当您返回 Json 时,框架将准备每个属性,实质上是触发 SQL 命令以延迟加载所有数据。

相反,您应该准备一个具有未附加到 EntityFramework 的具体属性的 ViewModel 类,并根据需要深度准备该对象。

当您的对象具有自身的某些属性时,可能会发生这种情况。 例如。

public object Employee()
{
    string ID {get; set;}
    string Name {get; set;}
    int Age {get; set;}
    Employee Boss{get; set;} //<-- here
}
var employee = new Employee();
return Json(employee,JsonRequestBehavior.AllowGet); //The Boss property will cause "RecursionLimit exceeded".

为了避免这种情况。 你可以做这样的事情:

var employee = new Employee();
var prepareForJson = new {
    ID = employee.ID,
    Name = employee.Name,
    Age = employee.Age,
    Boss = employee.Boss.ID
};
return Json(prepareForJson , JsonRequestBehavior.AllowGet);

您可以通过 web.config 配置递归深度

http://msdn.microsoft.com/en-us/library/bb763183.aspx

但你可能只是想整理你的模型,而不是首先有递归。想想在当前情况下需要多少数据并返回这些数据。

我认为Edison Chuang是绝大多数情况的答案(将数据模型映射到一些没有导航属性的服务模型,这些属性肯定会在序列化期间导致循环(。

但是,由于大多数服务模型将共享数据模型(EF 模型(的许多属性,因此可以使用 AutoMapper,从而大大简化了代码,尤其是对于具有许多属性的对象。 例如:

// set up map
cfg.CreateMap<Employee, EmployeeSm>();
// use the map
var sm = Mapper.Map<EmployeeSm>(employee);
// this can be also set up during mapping configuration phase
sm.Boss = employee.Boss.ID;

对于序列化深度超过默认值 100 的极少数情况,可以增加此限制或使用 Json.NET 来序列化对象。