我在使用Newtonsoft.Json从我的ASP.NET Web API控制器正确序列化数据时遇到问题.
这就是我的想法 - 如果我错了,请纠正我.在某些情况下(特别是当数据中没有任何循环引用时)一切都像您期望的那样 - 填充的对象列表被序列化并返回.如果我引入的数据导致模型中的循环引用(如下所述,甚至是PreserveReferencesHandling.Objectsset),则只有通过循环引用导致第一个对象的列表元素才能以客户端可以"使用"的方式进行序列化. ."元素导向"可以是数据中的任何元素,如果在将内容发送到序列化器之前以不同方式排序,但至少有一个元素将以客户端可以"使用"的方式序列化.空对象最终被序列化为Newtonsoft references({$ref:X}).
例如,如果我有一个EF模型,其导航属性如下所示:

在我的global.asax中:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
Run Code Online (Sandbox Code Playgroud)
这是我正在使用Entity Framework进行的基本查询(延迟加载已关闭,所以这里没有任何代理类):
[HttpGet]
[Route("starting")]
public IEnumerable<Balance> GetStartingBalances()
{
using (MyContext db = new MyContext())
{
var data = db.Balances
.Include(x => x.Source)
.Include(x => x.Place)
.ToList()
return data;
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止一直很好,data人口稠密.
如果没有循环引用,那么生命就是盛大的.但是,只要有2个Balance实体具有相同Source或者Place,那么序列化就会将Balance我返回的最顶层列表的后一个对象转换为Newtonsoft引用而不是它们的完整对象,因为它们已经在Balances属性中被序列化了所述的Source或Place(多个)对象:
[{"$id":"1","BalanceID":4,"SourceID":2,"PlaceID":2 ...Omitted for clarity...},{"$ref":"4"}]
Run Code Online (Sandbox Code Playgroud)
这个问题是,{$ref:4}即使我们人类了解正在发生的事情,客户也不知道该怎么做.在我的例子中,这意味着我不能使用AngularJS来ng-repeat …