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

如何解决多类型Value字段的JSON反序列化与重新序列化问题?

这个问题我太熟悉了!用object来存这种动态类型的Value字段,确实会在重新序列化时丢失原始的JSON结构信息——尤其是像field3这种嵌套对象,很容易被序列化成一堆键值对的字典格式,而不是原来的嵌套JSON。下面给你几个实用的解决办法,根据你用的JSON库来选就行:

方案1:用JsonElement(适配System.Text.Json)

如果你用的是.NET Core/.NET 5+自带的System.Text.Json,直接把Value的类型改成JsonElement就行,它能完美保留原始的JSON结构,反序列化和重新序列化都不会出问题:

using System.Text.Json.Serialization;

public class CustomField
{
    [JsonPropertyName("definition")]
    public string Definition { get; set; }

    [JsonPropertyName("value")]
    public JsonElement Value { get; set; }
}

public class RootObject
{
    [JsonPropertyName("id")]
    public string Id { get; set; }

    [JsonPropertyName("custom_fields")]
    public List<CustomField> CustomFields { get; set; }
}

使用的时候也很简单,反序列化后如果需要读取具体的Value值,可以用JsonElement的类型判断方法,比如:

// 读取field1的字符串值
var field1Value = customFields.First(f => f.Definition == "field1").Value.GetString();

// 读取field3的嵌套对象id
var field3UserId = customFields.First(f => f.Definition == "field3").Value.GetProperty("id").GetString();

重新序列化的时候,直接调用JsonSerializer.Serialize就能输出和原始JSON完全一致的结构。

方案2:用JToken(适配Newtonsoft.Json)

如果你项目里用的是Newtonsoft.Json(Json.NET),那把Value改成JToken是最省心的选择,它是Newtonsoft用来表示任意JSON元素的抽象类型,同样能完整保留原始结构:

using Newtonsoft.Json;

public class CustomField
{
    [JsonProperty("definition")]
    public string Definition { get; set; }

    [JsonProperty("value")]
    public JToken Value { get; set; }
}

public class RootObject
{
    [JsonProperty("id")]
    public string Id { get; set; }

    [JsonProperty("custom_fields")]
    public List<CustomField> CustomFields { get; set; }
}

读取具体值的示例:

// 读取field2的数组
var field2Values = customFields.First(f => f.Definition == "field2").Value.ToObject<List<string>>();

// 读取field3的嵌套对象
var field3User = customFields.First(f => f.Definition == "field3").Value.ToObject<User>();

重新序列化时,JToken会自动输出正确的JSON结构,完全不用担心嵌套对象的问题。

方案3:自定义转换器+强类型模型(适合需要类型安全的场景)

如果你希望代码有更强的类型约束,不想用JsonElement或JToken这种弱类型,可以自定义一个JSON转换器,根据definition字段来决定Value的类型。比如先定义几个可能的Value类型:

public class StringValue
{
    public string Value { get; set; }
}

public class ArrayValue
{
    public List<string> Value { get; set; }
}

public class UserValue
{
    public User Value { get; set; }
}

public class User
{
    public string Type { get; set; }
    public string Id { get; set; }
}

然后写一个自定义转换器继承JsonConverter<object>(或者针对CustomField的转换器),在反序列化时根据definition来解析对应的Value类型,序列化时再反向处理。不过这个方案相对复杂一些,适合对类型安全要求很高的场景。

为什么用object会出问题?

本质原因是:反序列化时,JSON里的嵌套对象会被默认转换成JsonElement(System.Text.Json)或JObject(Newtonsoft),但当你把它们存在object类型的属性里,重新序列化时,序列化器无法识别它们原本的JSON结构,会把它们当成普通的.NET对象来序列化,比如把JObject序列化成字典格式,导致输出的JSON和原始结构不一致。

内容的提问来源于stack exchange,提问作者Wim Rijken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:09:29