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

C#如何反序列化data字段类型动态的JSON数据?

解决System.Text.Json反序列化多类型data字段的问题

当前API返回两种格式的JSON响应:

  • 错误响应(Type 1):
{
    "type": "error",
    "data": "error message"
}
  • 成功响应(Type 2):
{
    "type": "success",
    "data": [
        {
            "id": 1,
            "title": "tortor at auctor urna nunc",
            "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        },
        {
            "id": 2,
            "title": "gravida rutrum quisque non tellus",
            "content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
        }
    ]
}

原ResponseData类将Data定义为string类型,反序列化Type 2响应时会抛出System.Text.Json.JsonException——因为JSON数组无法直接转换为字符串。需求是:无论data字段是字符串、数组还是整数,都将其转为JSON字符串存入responseData.Data,后续可再反序列化为DataList对象。

以下是两种可行解决方案:

方案一:自定义JsonConverter处理Data字段

编写自定义转换器,自动判断JSON值类型:如果是字符串直接返回,否则将该值序列为JSON字符串。

代码实现

using System.Text.Json;
using System.Text.Json.Serialization;

class ResponseData
{
    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("data")]
    [JsonConverter(typeof(AnyTypeToStringConverter))]
    public string Data { get; set; }
}

public class AnyTypeToStringConverter : JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            return reader.GetString();
        }
        using var document = JsonDocument.ParseValue(ref reader);
        return document.RootElement.GetRawText();
    }

    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        if (JsonSerializer.Deserialize<JsonElement>(value) is var element)
        {
            element.WriteTo(writer);
        }
        else
        {
            writer.WriteStringValue(value);
        }
    }
}

使用方式

保持原有反序列化代码即可:

var response = await httpClient.GetAsync(url);
var responseData = await response.Content.ReadFromJsonAsync<ResponseData>();
Debug.WriteLine(responseData.Data);

// 后续反序列化DataList
if (responseData.Type == "success")
{
    var dataList = JsonSerializer.Deserialize<DataList>(responseData.Data);
    // 处理dataList逻辑
}

方案二:先反序列化为JsonElement再转换

通过中间类接收响应,将data字段用JsonElement类型暂存,再手动转为JSON字符串。

代码实现

using System.Text.Json;

// 中间过渡类,用JsonElement接收任意类型的data
class ResponseDataInterim
{
    [JsonPropertyName("type")]
    public string Type { get; set; }

    [JsonPropertyName("data")]
    public JsonElement Data { get; set; }
}

// 反序列化流程
var response = await httpClient.GetAsync(url);
var interimData = await response.Content.ReadFromJsonAsync<ResponseDataInterim>();

var responseData = new ResponseData
{
    Type = interimData.Type,
    Data = interimData.Data.GetRawText()
};

Debug.WriteLine(responseData.Data);

// 后续反序列化DataList
if (responseData.Type == "success")
{
    var dataList = JsonSerializer.Deserialize<DataList>(responseData.Data);
    // 处理dataList逻辑
}

两种方案均可实现需求:Type 1的data直接以字符串存入,Type 2的数组转为JSON字符串存入,后续能正常反序列化为DataList对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 11:45:21