大多数时候,默认情况下,我们没有在我们选择的静态语言中定义类,这让白色在如何反序列化例如从调用公共(public)和开放的 wen api 返回的 JSON,除了例如“语言”之外,不专用于任何一种语言。 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
迷宫的所有令人困惑的官僚主义。
难道就没有其他方法可以像在其他场景下解析成显式动态JavaScript对象一样,简单地将JSON解析成C#动态对象吗?
添加:“混淆了他们的 JObject 迷宫的官僚机构”,我的意思是以下代码:
var json = JsonConvert.SerializeObject(new Person {Id = 196912135012878, Age = 47, Name = "Brady"});
var jObj = JsonConvert.DeserializeObject(json);
生成一个 JObject
实例,我的调试器显示为:
在我看来,这更像是应该在 JSON 解析期间在内部使用的东西,而不是该解析的最终产品,它应该只是从该 JSON 解析的属性的纯粹表示。理想情况下,这将是一个没有任何解析器使用的属性的 C# 动态对象。
最佳答案
而不是 JObject
,您可以反序列化为 ExpandoObject
,这是由 Json.NET 的内置转换器支持的 ExpandoObjectConverter
.如果是数组,您可以反序列化为 List<ExpandoObject>
然后选择一个List<dynamic>
.如果是原始值,您可以返回 JValue.Value
.
例如,如果您事先知道您的 JSON 表示一个对象,只需执行以下操作:
dynamic dyn = JsonConvert.DeserializeObject<ExpandoObject>(json);
如果您事先不知道根 JSON 容器可能是什么,您可以将其加载为 JToken
并使用以下扩展方法:
public static class JsonExtensions
{
public static dynamic ToDynamic(this JToken token)
{
if (token == null)
return null;
else if (token is JObject)
return token.ToObject<ExpandoObject>();
else if (token is JArray)
return token.ToObject<List<ExpandoObject>>().Cast<dynamic>().ToList();
else if (token is JValue)
return ((JValue)token).Value;
else
// JConstructor, JRaw
throw new JsonSerializationException(string.Format("Token type not implemented: {0}", token));
}
}
然后做:
dynamic dyn = JsonConvert.DeserializeObject<JToken>(json).ToDynamic();
样本 fiddle .
关于c# - 如何从 Web API JSON 响应派生 C# 动态对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42430116/