c# - 如何从 Web API JSON 响应派生 C# 动态对象?

标签 c# json serialization dynamic json.net

大多数时候,默认情况下,我们没有在我们选择的静态语言中定义类,这让白色在如何反序列化例如从调用公共(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 实例,我的调试器显示为:

Debugger view of JObject properties

在我看来,这更像是应该在 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/

相关文章:

c++ - 将其中包含结构的 vector 序列化为 .dat 文件时,我做错了什么?

asp.net-core - 使用 .Net Core API 进行元组序列化

c# - 编译时/构建后依赖注入(inject) IoC?

c# - 如何在 WinForms 中强制用户使用管理员帐户

javascript - 如何找到 json 文件的长度?

json - 将 JSON 数据导入到 REACTJS 中的数组中

Python使用json读取一个带表情的字符串

python - 保存对象(数据持久性)

c# - 我应该先将参数值分配给局部变量而不是直接使用它们吗?

c# - Entity Framework -与Oracle和SQL Server交互