【发布时间】:2017-07-14 18:46:39
【问题描述】:
在大多数情况下,默认情况下,我们没有在我们选择的静态语言中定义类,这让白在如何反序列化例如JSON 从对公共和开放 wen api 的调用返回,专用于没有单一语言,除了例如的“语言”。 HTML 和 JSON。
如今,在 .NET 中,几乎所有 api 查询都使用 HttpClient 完成,类似于下面的 Google Books API ISBN 查询:
public class GoogleBooksClient
{
private const string IsbnUrl = "books/v1/volumes?q=isbn:{0}";
private static HttpClient _client = new HttpClient();
...
public async Task<object> GetDetailsByIsbn(string isbn)
{
var json = await _client.GetStringAsync(string.Format(IsbnUrl, isbn));
dynamic objX = JsonConvert.DeserializeObject(json);
return objX;
}
}
这里最大的问题是objX是否被声明为var'、object或dynamic,当DeserializeObject被调用时,它总是引用一个又大又丑的JObject实例已知类型。在这种情况下,返回的 JSON 对象非常复杂,等待那些努力编写可以解析 JSON 的 C# 类的人。
这是使用 C# dynamic 对象的理想且有意的机会,在解析 JSON 时,可以将属性(很少用于 API 响应的函数)递归地添加到所述动态对象中。
相反,NewtonSoft.JSON 将 JSON 保存的数据与非常不透明的 Jobject 数据结构的繁文缛节紧密结合在一起。我很惊讶也很失望,到目前为止,NewtonSoft 不能简单地提取一个纯动态对象,而没有他们JObject 迷宫的所有令人费解的官僚机构。
有没有其他方法可以简单地将 JSON 解析为 C# 动态对象,就像在其他场景中将其解析为显式动态 JavaScript 对象一样?
添加:“混淆他们 JObject 迷宫的官僚作风”,我的意思是以下代码:
var json = JsonConvert.SerializeObject(new Person {Id = 196912135012878, Age = 47, Name = "Brady"});
var jObj = JsonConvert.DeserializeObject(json);
产生一个JObject 实例,我的调试器显示为:
在我看来,这更像是在解析 JSON 期间应该在内部使用的东西,而不是解析的最终产品,它应该是仅从该 JSON 解析的属性的纯粹表示。理想情况下,这将是一个没有任何属性的 C# 动态对象,可供任何解析器使用。
【问题讨论】:
-
对于
JObject类型的令牌(而不是JArray),您可以反序列化为ExpandoObject。见newtonsoft.com/json/help/html/SerializationGuide.htm#Dynamic。不太确定你的问题是什么。 混淆他们 JObject 迷宫的官僚作风是什么意思? -
@dbc 添加了我不喜欢
JObject的原因。感谢ExpandoObject提示。这确实很有帮助。 -
@dbc 顺便说一下,dman2306 的链接与
JObject到dynamic以及JArray一样有效。虽然我认为我的最终目标是将 Json.NET 配置为始终在输出 json 中包含类型名称,但我可以为该类型做一个快速的脏樱桃挑选,然后正确反序列化为类型。我并不总是自己做序列化:ASP.NET 经常为我做。 -
@dbc 请让
ExpandoObject解决方案成为我会接受的答案。感觉恰到好处,并且省略了外部的非 BCL 类。
标签: c# json serialization dynamic json.net