You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Json.NET或其他类库反序列化含动态命名属性的API返回JSON

如何使用Json.NET或其他类库反序列化含动态命名属性的API返回JSON

我太懂你这种困扰了——API返回的JSON里藏着个属性名动态变化的字段,虽然格式固定但后缀ID每次都不一样,常规的类定义根本没法直接映射对吧?我之前也处理过几乎一模一样的场景,用Json.NET完全能搞定,下面给你一步步拆解方案:

1. 先定义基础类结构

首先,咱们先把固定属性和动态属性对应的结构理清楚:

  • 那个动态属性里的__deferred是固定结构,先单独定义一个类:
public class Deferred
{
    public string uri { get; set; }
}
  • 然后是每个entry的类,固定属性直接明确定义,动态属性用Json.NET的[JsonExtensionData]特性来承接——这个特性专门用来处理JSON里那些没有对应类属性的“额外”键值对,刚好适配咱们的场景:
public class Entry
{
    // 这些都是固定属性,直接对应JSON里的字段
    public string cuid { get; set; }
    public string name { get; set; }
    public string description { get; set; }
    public string id { get; set; }
    public string type { get; set; }
    public string ownerid { get; set; }
    public string updated { get; set; }
    public string parentid { get; set; }

    // 用这个字典接收所有动态命名的属性
    [JsonExtensionData]
    public Dictionary<string, JToken> DynamicProperties { get; set; }
}
  • 最后是整个API返回的根对象,用来包裹entries数组:
public class ApiResponse
{
    public List<Entry> entries { get; set; }
}

2. 执行反序列化操作

有了类结构,反序列化就很简单了,一行代码搞定:

// 把apiResponseJson替换成你实际拿到的API返回字符串
var apiResponse = JsonConvert.DeserializeObject<ApiResponse>(apiResponseJson);

3. 提取动态属性内容

因为你知道动态属性的名字格式是https://bi.com/biprws/v1/documents/{数字ID},咱们可以用正则匹配来精准找到它:

foreach (var entry in apiResponse.entries)
{
    // 匹配符合格式的动态属性键
    var documentPropertyKey = entry.DynamicProperties.Keys.FirstOrDefault(key => 
        Regex.IsMatch(key, @"^https://bi.com/biprws/v1/documents/\d+$"));

    if (documentPropertyKey != null)
    {
        // 如果你需要属性里的__deferred内容,就转成Deferred对象
        var deferredData = entry.DynamicProperties[documentPropertyKey].ToObject<Deferred>();
        Console.WriteLine($"文档URI: {deferredData.uri}");
        
        // 你之前说只要动态属性的名字就够用,那直接取documentPropertyKey就行
        Console.WriteLine($"动态属性名称: {documentPropertyKey}");
    }
}

4. 备选方案:用System.Text.Json(无需额外安装包)

如果你不想用Json.NET,.NET Core/.NET 5+自带的System.Text.Json也能实现,思路差不多,只是类定义和反序列化方法略有不同:

  • 把Entry类里的Dictionary<string, JToken>换成Dictionary<string, JsonElement>,特性还是[JsonExtensionData]
  • 反序列化用JsonSerializer.Deserialize<ApiResponse>(apiResponseJson)

另外你提到之前看到的那个关于动态数字键的帖子,虽然它没法完全满足你的场景,但咱们这个方案刚好补上了缺口——既能完整保留所有固定属性的映射,又能灵活处理动态命名的字段,完全适配你的需求。

备注:内容来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.23 10:37:46