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

如何用Json.Net自动反序列化两种格式存储的Values类对象?

这问题我之前处理过类似的场景,用自定义JsonConverter完全能搞定!核心思路就是在反序列化时判断输入的JSON是字符串还是对象,然后分别做处理。下面给你唠唠具体实现步骤,分两种常用的JSON库来讲解:

方案一:使用Newtonsoft.Json(Json.NET)

这是.NET生态里最常用的JSON处理库,实现起来很直观:

1. 自定义JsonConverter类

这个转换器会负责判断JSON类型,分别处理字符串和对象两种情况:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class ValuesConverter : JsonConverter<Values>
{
    public override Values ReadJson(JsonReader reader, Type objectType, Values existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 先判断当前JSON的token类型
        if (reader.TokenType == JsonToken.String)
        {
            // 如果是字符串,直接构造Values实例
            string singleValue = (string)reader.Value;
            return new Values
            {
                BestValue = 0, // 这里可以根据你的业务需求设置默认值
                AllValues = new List<string> { singleValue }
            };
        }
        else if (reader.TokenType == JsonToken.StartObject)
        {
            // 如果是对象,用JObject转成Values实例
            JObject jObject = JObject.Load(reader);
            return jObject.ToObject<Values>(serializer);
        }

        // 遇到未知类型可以抛异常或者返回null,根据需求调整
        throw new JsonSerializationException("反序列化Values时遇到意外的Token类型");
    }

    public override void WriteJson(JsonWriter writer, Values value, JsonSerializer serializer)
    {
        // 序列化时也可以做反向处理:如果AllValues只有一个元素,就序列化成字符串
        if (value.AllValues != null && value.AllValues.Count == 1)
        {
            writer.WriteValue(value.AllValues[0]);
        }
        else
        {
            // 否则正常序列化成对象
            serializer.Serialize(writer, value);
        }
    }
}

2. 应用转换器

有两种方式可以让转换器生效:

方式一:给Values类加特性标记

直接在类上标注转换器,这样所有序列化/反序列化操作都会自动用它:

[JsonConverter(typeof(ValuesConverter))]
public class Values
{
    public int BestValue { get; set; }
    public List<string> AllValues { get; set; }
}

方式二:序列化/反序列化时手动指定

如果不想全局生效,也可以在调用方法时传入转换器:

// 反序列化字符串格式的JSON
string singleValueJson = "\"MyFirstValue\"";
Values singleValue = JsonConvert.DeserializeObject<Values>(singleValueJson, new ValuesConverter());

// 反序列化对象格式的JSON
string objectJson = "{\"BestValue\" : 0, \"AllValues\" : [\"DefaultValue\", \"OtherValue\"]}";
Values objectValue = JsonConvert.DeserializeObject<Values>(objectJson, new ValuesConverter());
方案二:使用System.Text.Json(.NET Core 3.0+内置)

如果用的是.NET Core或.NET 5+的内置JSON库,实现思路类似,只是接口略有不同:

1. 自定义JsonConverter类

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

public class ValuesConverter : JsonConverter<Values>
{
    public override Values Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            string singleValue = reader.GetString();
            return new Values
            {
                BestValue = 0,
                AllValues = new List<string> { singleValue }
            };
        }
        else if (reader.TokenType == JsonTokenType.StartObject)
        {
            // 直接用内置方法反序列化对象
            return JsonSerializer.Deserialize<Values>(ref reader, options);
        }

        throw new JsonException("反序列化Values时遇到意外的Token类型");
    }

    public override void Write(Utf8JsonWriter writer, Values value, JsonSerializerOptions options)
    {
        if (value.AllValues != null && value.AllValues.Count == 1)
        {
            writer.WriteStringValue(value.AllValues[0]);
        }
        else
        {
            JsonSerializer.Serialize(writer, value, options);
        }
    }
}

2. 应用转换器

同样有两种方式:

方式一:给类加特性标记

[JsonConverter(typeof(ValuesConverter))]
public class Values
{
    public int BestValue { get; set; }
    public List<string> AllValues { get; set; }
}

方式二:通过JsonSerializerOptions指定

var options = new JsonSerializerOptions();
options.Converters.Add(new ValuesConverter());

// 反序列化字符串格式
Values singleValue = JsonSerializer.Deserialize<Values>("\"MyFirstValue\"", options);

// 反序列化对象格式
Values objectValue = JsonSerializer.Deserialize<Values>("{\"BestValue\" : 0, \"AllValues\" : [\"DefaultValue\", \"OtherValue\"]}", options);
小提示
  • 关于BestValue的默认值:如果字符串场景下需要设置其他默认值(比如1或者-1),直接修改转换器里对应的值就行。
  • 异常处理:如果遇到除了字符串和对象之外的类型,你可以根据业务需求选择返回null或者抛出更具体的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:04:11