- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在使用 Newtonsoft.Json 从我的 ASP.NET Web API Controller 正确序列化某些数据时遇到问题。
这就是我认为 正在发生的事情 - 如果我错了请纠正我。在某些情况下(特别是当数据中没有任何循环引用时)一切都像您期望的那样工作 - 填充对象列表被序列化并返回。如果我在模型中引入导致循环引用的数据(如下所述,甚至设置了 PreserveReferencesHandling.Objects
),则只有指向具有循环引用的第一个对象的列表中的元素才会序列化客户可以“使用”的一种方式。如果在将内容发送到序列化程序之前排序不同,则“导致的元素”可以是数据中的任何元素,但至少有一个将以客户端可以“使用”的方式序列化。空对象最终被序列化为 Newtonsoft 引用 ({$ref:X}
)。
例如,如果我有一个带有导航属性的 EF 模型,如下所示:
在我的 global.asax 中:
var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
这是我使用 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;
}
}
到目前为止一切顺利,data
已填充。
如果没有循环引用,生活就是美好的。但是,一旦有 2 个 Balance
实体具有相同的 Source
或 Place
,序列化就会变成后面的 Balance
我返回到 Newtonsoft 引用的最顶层列表的对象而不是它们的完整对象,因为它们已经在 Source
的 Balances
属性中序列化或 Place
对象:
[{"$id":"1","BalanceID":4,"SourceID":2,"PlaceID":2 ...Omitted for clarity...},{"$ref":"4"}]
这个问题是客户端不知道如何处理 {$ref:4}
,即使我们人类明白发生了什么。就我而言,这意味着我不能使用 AngularJS 通过此 JSON 在我的整个余额列表上 ng-repeat
,因为它们并非都是真正的 Balance
对象Balance
属性进行绑定(bind)。我敢肯定还有很多其他用例会遇到同样的问题。
我无法关闭 json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects
因为很多其他的事情会中断(这在 100 个其他问题中有详细记录在这里和其他地方).
除了遍历 Web API Controller 中的实体并执行此操作之外,是否有更好的解决方法
Balance.Source.Balances = null;
所有的导航属性来打破循环引用?因为这似乎也不对。
最佳答案
是的,使用 PreserveReferencesHandling.Objects
确实是使用循环引用序列化对象图的最佳方式,因为它生成最紧凑的 JSON,并且实际上保留了对象图的引用结构。也就是说,当您将 JSON 反序列化回对象时(使用理解 $id
和 $ref
符号的库),对特定对象的每个引用都将指向该对象的相同实例,而不是具有具有相同数据的多个实例。
在你的情况下,问题是你的客户端解析器不理解 Json.Net 生成的 $id
和 $ref
符号,所以引用没有被解决。这可以通过在反序列化 JSON 后使用 javascript 方法重建对象引用来解决。参见 here和 here举些例子。
根据您的情况,另一种可行的方法是在序列化时将 ReferenceLoopHandling
设置为 Ignore
而不是将 PreserveReferencesHandling
设置为 对象
。但这不是一个完美的解决方案。参见 this question有关使用 ReferenceLoopHandling.Ignore
和 PreserveReferencesHandling.Objects
之间差异的详细说明。
关于c# - 如何使用 Newtonsoft.Json 序列化 "Really"循环引用对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26434738/
我在谷歌上花了很长时间,所以如果这是一个简单的修复请原谅我,但我找不到任何与 C# 中这个特定问题的修复相关的内容。 当尝试使用以下代码时,出现此错误: string obj = JsonConver
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 去年关闭。 Improve this
我正在尝试重新创建这个 json: { "request": { " TestRequest": { "OrderID": {
我正在测试我的 Web API。模拟数据我有这个: var objs = ((JArray)JsonConvert.DeserializeObject("{ \"PrintId\":10,\"Head
目前正在尝试使用 fixer.io API 在 C# 中创建货币转换。 我在从 Twitter API 解析 JSON 时使用了与下面类似的方法,并且没有任何问题,我不完全确定这里发生了什么。 API
我正在尝试建立 Mike Jansen 的 JIRA REST Client ,我正在尝试提取 JIRA 版本信息。我是 JSON 的新手,所以我不确定这只是格式问题还是什么。 调试时,我有以下标记:
我正在尝试使用 将对象动态序列化到即时窗口中 Newtonsoft.Json.JsonConvert.SerializeObject(myObj); 但是我得到以下错误 The type 'Newto
我无法在 Visual Studio 2013 中构建解决方案。 这发生在我将我的 JSON.NET 包更新到 6.0.1 之后。在此之前,它就像一个魅力。 有什么想法吗? PS:这可能是关于 OWI
当有如下代码时 var TermSource = token.Value("annotations") .Values("Term Source") .FirstOrDefault
我需要将选中的复选框代码从 JavaScript 传递给 C#。我能够通过 JSON 发送代码。我的 JSON 值以 JArray 的形式出现。我在标题中得到了异常(exception)。 JSON:
注意:解决重定向问题后,我遇到了另一个问题,即出现错误“无法将 Newtonsoft.Json.Linq.JArray 转换为 Newtonsoft.Json.Linq.JToken”。因此,在我的回
我有以下简单的 POCO: public class ApiKey { public ApiKey(string key, string owner, List claims = nu
我查过这个问题,但我没有看到太多答案,显然没有一个有帮助,否则我不会问。我是 .NET 新手。 我的本地环境是Win7,Microsoft Virtual Web Developer 2010 Exp
好的-我已经将这个问题打了几个小时。是时候寻求帮助了。 我刚刚将Web应用程序项目升级到ASP.NET MVC 4 RC和新的WebApi。 我的Web api方法现在返回EMPTY json“{}”
我想忽略类中的某些属性,但出于多种原因我想保留类 POCO。因此我不想引入对 Json.NET 的依赖,也不想使用 JsonIgnoreAttribute。 有没有办法自定义契约(Contract)解
我正在尝试修复我编写的 WinForms 程序中的错误;我正在解析一个 JSON 字符串,然后将一些结果放入各种变量中。 有时,JSON 的特定元素不存在(出于真正的原因),因此我尝试使用以下代码来处
我只是尝试使用 C# 中的 Newtonsoft JSON 库将文件中的一些 JSON 反序列化为对象列表。以下是 MeetingFile.txt 文件的内容: [ { "People":
这是一个非常奇怪的错误发生。我有这些对象: public class Mobile_SettingModels { public string Token { get; set; }
我粘贴了 http://www.codeproject.com/Tips/789481/Bridging-the-Gap-between-Linqpad-and-Visual-Studio 中的代码进
这个问题在这里已经有了答案: Can I optionally turn off the JsonIgnore attribute at runtime? (3 个答案) 关闭 4 年前。 我目前正
我是一名优秀的程序员,十分优秀!