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

如何将API返回的带编号属性的JSON反序列化为C# Ticket对象?

优化JSON到C# Ticket类的反序列化方案

针对你遇到的JSON结构与目标C#类不匹配的问题,推荐使用自定义JSON转换器的方案,比手动遍历字典更优雅且易维护,下面给出两种主流JSON库的实现方式:

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

步骤1:定义匹配JSON结构的中间类

先定义能直接映射原始JSON的临时类,用于承接反序列化的中间结果:

// 单个字段的结构
public class TicketField
{
    public string DisplayName { get; set; }
    public object Value { get; set; }
}

// 外层包裹类
public class TicketWrapper
{
    public Dictionary<string, TicketField> Ticket { get; set; }
}

步骤2:编写自定义转换器

实现JsonConverter<Ticket>,将中间结构转换为目标Ticket类:

public class TicketConverter : JsonConverter<Ticket>
{
    // 提前配置DisplayName到属性的映射逻辑,避免硬编码switch
    private static readonly Dictionary<string, Action<Ticket, object>> _fieldMappings = new()
    {
        {"Ticket ID", (ticket, val) => ticket.TicketID = Convert.ToInt32(val)},
        {"Last Modified", (ticket, val) => ticket.LastModified = DateTime.Parse((string)val)},
        {"Last User", (ticket, val) => ticket.LastUser = (string)val},
        {"Seq_Group", (ticket, val) => ticket.Seq_Group = Convert.ToInt32(val)}
        // 新增字段只需在这里添加映射项
    };

    public override Ticket ReadJson(JsonReader reader, Type objectType, Ticket existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 先反序列化为中间类
        var wrapper = serializer.Deserialize<TicketWrapper>(reader);
        var ticket = new Ticket();

        // 遍历字段并应用映射
        foreach (var field in wrapper.Ticket.Values)
        {
            if (_fieldMappings.TryGetValue(field.DisplayName, out var setProperty))
            {
                setProperty(ticket, field.Value);
            }
        }

        return ticket;
    }

    // 如果不需要将Ticket序列化为原始JSON格式,可暂不实现WriteJson
    public override void WriteJson(JsonWriter writer, Ticket value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

步骤3:使用转换器反序列化

string json = "你的API返回JSON字符串";
Ticket ticket = JsonConvert.DeserializeObject<Ticket>(json, new TicketConverter());

方案二:使用System.Text.Json(.NET Core/.NET 5+内置)

如果使用官方内置的JSON库,实现逻辑类似:

步骤1:定义中间类

注意Value用JsonElement类型兼容不同数据类型:

public class TicketField
{
    public string DisplayName { get; set; }
    public JsonElement Value { get; set; }
}

public class TicketWrapper
{
    public Dictionary<string, TicketField> Ticket { get; set; }
}

步骤2:编写自定义转换器

public class TicketConverter : JsonConverter<Ticket>
{
    private static readonly Dictionary<string, Action<Ticket, JsonElement>> _fieldMappings = new()
    {
        {"Ticket ID", (ticket, val) => ticket.TicketID = val.GetInt32()},
        {"Last Modified", (ticket, val) => ticket.LastModified = val.GetDateTime()},
        {"Last User", (ticket, val) => ticket.LastUser = val.GetString()},
        {"Seq_Group", (ticket, val) => ticket.Seq_Group = val.GetInt32()}
    };

    public override Ticket Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var wrapper = JsonSerializer.Deserialize<TicketWrapper>(ref reader, options);
        var ticket = new Ticket();

        foreach (var field in wrapper.Ticket.Values)
        {
            if (_fieldMappings.TryGetValue(field.DisplayName, out var setProperty))
            {
                setProperty(ticket, field.Value);
            }
        }

        return ticket;
    }

    public override void Write(Utf8JsonWriter writer, Ticket value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

步骤3:使用转换器反序列化

string json = "你的API返回JSON字符串";
var options = new JsonSerializerOptions();
options.Converters.Add(new TicketConverter());
Ticket ticket = JsonSerializer.Deserialize<Ticket>(json, options);

方案优势

  • 代码结构清晰,新增字段只需更新映射字典,无需修改核心逻辑
  • 避免大量重复的分支判断,可维护性更高
  • 符合JSON库的扩展规范,逻辑更贴合序列化/反序列化的流程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:55:27