3

我正在尝试通过 ASP.NET MVC 前端层从我的服务器返回一个 JSON 列表:

var stuff = repo.GetStuff();
return Json(stuff);

但是,我收到一条错误消息,而不是预期的 JSON

序列化“System.Reflection.RuntimeModule”类型的对象时检测到循环引用。

我想我已经找到了发生这种情况的地方,但是为了解释它,我需要一个简单的示例域模型,如下所示:

在此处输入图像描述

我正在(懒惰地?)从 NHibernate 加载一系列文档,如下所示:

var session = getNHibernateSession();
var query = new NhQueryable<Document>(session.GetSessionImplementation());
var docs = query.ToList().AsEnumerable();

JsonResult然后我传递文件以在我的控制器中返回 a :

return Json(docs, JsonRequestBehavior.AllowGet);

现在,当Json()对集合进行序列化时,它会遍历文档的属性,找到一个人。它序列化那个人,并找到一个项目。它对项目进行序列化,并再次找到 - 没错 - 那个人!由于我是延迟加载,所以如果没有什么能阻止它,它可以一直走下去,但它会因循环引用错误而停止。

我真的不需要降低所有这些级别(如果不首先加载项目我会很好) - 我可以以某种方式影响Json()这个集合的序列化方式,而不是进一步降低,比如说,降低 2 级吗?我搜索了一下,但我发现的大部分内容似乎来自那些决定直接使用序列化库的人,而不仅仅是使用 .NET MVC 中的内置功能。(注意:这个问题的解决方案必须可以专门应用于这种情况,因为我可能想要在应用程序的其他地方获取人员的 JSON 列表,包括项目......)

4

3 回答 3

1

如果您正在检索 Json,则您有一个服务 api。除了实现之外,您还必须设计 api。将使用它的页面是否需要所有这些字段和集合?可能不是。为其他功能和服务添加更多属性怎么样?它们将开始出现在所有请求中。

您需要使用 ViewModel 或仅使用具有所需结构的匿名类型:

var session = getNHibernateSession();
var query = new NhQueryable<Document>(session.GetSessionImplementation());
var docs = query.ToList();
var result = query.Select(x => new {
                                       x.Id,
                                       x.Name,
                                       People = new { p.Id, 
                                                      p.Name, 
                                                      p.Title
                                                    }
                                    });

return Json( result, JsonRequestBehavior.AllowGet);

通过这种方式,您可以控制渲染的内容和方式。

于 2012-06-20T14:09:55.950 回答
0

这里已经回答了。

此外,像这样公开您的域实体通常不是一个好主意。如果它是用于只读目的,它可能不会那么糟糕,但是如果您的任何操作方法接受域实体,那么特定格式的请求可以覆盖您不想要的域实体上的属性(例如您的 PK )。

于 2012-06-20T13:57:09.660 回答
0

要在 JSON 中保留对象引用,请将以下代码添加到Global.asax文件中的Application_Start方法:

var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.All;
于 2014-04-07T10:06:06.963 回答