小编jgo*_*ein的帖子

你如何"真正"使用Newtonsoft.Json序列化循环引用对象?

我在使用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属性中被序列化了所述的SourcePlace(多个)对象:

[{"$id":"1","BalanceID":4,"SourceID":2,"PlaceID":2 ...Omitted for clarity...},{"$ref":"4"}]
Run Code Online (Sandbox Code Playgroud)

这个问题是,{$ref:4}即使我们人类了解正在发生的事情,客户也不知道该怎么做.在我的例子中,这意味着我不能使用AngularJS来ng-repeat …

c# json entity-framework json.net asp.net-web-api

16
推荐指数
1
解决办法
1万
查看次数

标签 统计

asp.net-web-api ×1

c# ×1

entity-framework ×1

json ×1

json.net ×1