9

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

return Json(myUser,JsonRequestBehavior.AllowGet);

当我加载页面时,大约需要 30 秒,然后我收到错误“超出 RecursionLimit”。

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

4

4 回答 4

8

myUser可能是EntityFramework生成的类型。

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

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

于 2012-05-21T01:46:23.670 回答
6

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

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);
于 2012-05-21T01:58:58.683 回答
3

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

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

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

于 2012-05-21T01:46:50.500 回答
0

我认为这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序列化对象。

于 2018-03-14T08:04:25.783 回答