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

如何将JSON反序列化为包含自定义struct结构的C#对象?

问题原因

  • Newtonsoft.Json(Json.NET)默认无法自动触发Content到ContentStructure的隐式转换:当JSON中content节点为对象类型时,Json.NET只会尝试将节点属性与ContentStructure的成员直接匹配,而ContentStructure没有和JSON里id、duration对应的成员,最终只会生成默认值的ContentStructure实例,因此ContentClass为null。
  • 当content为字符串类型时,Json.NET可以匹配到你定义的string到ContentStructure隐式转换,因此ContentString可以正常赋值。
  • 额外说明:ContentStructure中的ContentClass、ContentString是公共字段而非属性,默认情况下Json.NET反序列化只会处理公共属性,即使类型匹配也不会自动给公共字段赋值。

解决方案

最稳妥的方式是为ContentStructure自定义JsonConverter,指定不同JSON节点类型的处理逻辑:

步骤1:实现自定义转换器

using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class ContentStructureConverter : JsonConverter<ContentStructure>
{
    public override ContentStructure ReadJson(JsonReader reader, Type objectType, ContentStructure existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        // JSON节点是字符串,赋值给ContentString
        if (token.Type == JTokenType.String)
        {
            return token.ToObject<string>();
        }
        // JSON节点是对象,反序列化为Content后赋值给ContentClass
        else if (token.Type == JTokenType.Object)
        {
            return token.ToObject<Content>();
        }
        // 其他异常场景可按业务需求调整,这里返回默认值
        return default;
    }

    public override void WriteJson(JsonWriter writer, ContentStructure value, JsonSerializer serializer)
    {
        // 序列化逻辑,按需实现
        if (!string.IsNullOrEmpty(value.ContentString))
        {
            writer.WriteValue(value.ContentString);
        }
        else
        {
            serializer.Serialize(writer, value.ContentClass);
        }
    }
}

步骤2:注册转换器

两种注册方式二选一即可:

  1. 直接给ContentStructure添加特性标记:
[JsonConverter(typeof(ContentStructureConverter))]
public struct ContentStructure
{
    public Content ContentClass;
    public string ContentString;

    public static implicit operator ContentStructure(Content content) => new ContentStructure { ContentClass = content };
    public static implicit operator ContentStructure(string @string) => new ContentStructure { ContentString = @string };
}
  1. 反序列化时全局注册转换器:
var deserializeSettings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new ContentStructureConverter() }
};
var result = JsonConvert.DeserializeObject<Settings>(你的JSON字符串, deserializeSettings);

调整后即可同时兼容字符串和对象类型的content节点反序列化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 19:54:03