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

RestSharp反序列化非标准JSON数组,DataGridView无数据显示求助

解决RestSharp反序列化动态键JSON并绑定DataGridView的问题

你的问题核心在于JSON的data数组里每个元素都是仅包含一个动态设备ID键的对象,而你当前的实体类结构虽然能完成反序列化,但生成的List<GpsEquipo>里每个GpsEquipo的Dictionary只有一个键值对,DataGridView无法自动解析这种嵌套结构,导致数据无法显示。另外还有一个小问题:JSON里的status是数字类型(200),但你定义的RootObject里status是string,这会导致反序列化时类型不匹配。

下面给你两种可行的解决方案:

方案1:修改实体类结构并手动转换数据

这种方式简单直接,不需要自定义转换器,适合快速解决问题:

步骤1:调整实体类

首先修正RootObject的status类型,同时将data改为List<Dictionary<string, GpsOdometro>>,因为数组里的每个元素本身就是一个单键字典:

public class GpsOdometro {
    public string Fecha { get; set; }
    public string Kilometros { get; set; }
    public string Odometro { get; set; }
    public string Horas { get; set; }
}

public class RootObject {
    public int status { get; set; } // 改为int匹配JSON的数字类型
    public List<Dictionary<string, GpsOdometro>> data { get; set; }
}

然后创建一个用于DataGridView显示的扁平实体类(把设备ID和GPS数据放在同一层级):

public class GpsDisplayItem {
    public string DeviceId { get; set; } // 新增设备ID字段
    public string Fecha { get; set; }
    public string Kilometros { get; set; }
    public string Odometro { get; set; }
    public string Horas { get; set; }
}

步骤2:反序列化并转换数据

反序列化后,把嵌套的字典结构转换成扁平的GpsDisplayItem列表,这样就能直接绑定到DataGridView:

IRestResponse json = client.Execute(request);
RootObject result = JsonConvert.DeserializeObject<RootObject>(json.Content);

// 转换为适合显示的扁平结构
var displayList = result.data
    .SelectMany(dict => dict.Select(kv => new GpsDisplayItem {
        DeviceId = kv.Key,
        Fecha = kv.Value.Fecha,
        Kilometros = kv.Value.Kilometros,
        Odometro = kv.Value.Odometro,
        Horas = kv.Value.Horas
    }))
    .ToList();

// 绑定到DataGridView
DgOdometro.DataSource = displayList;

方案2:自定义JsonConverter一步到位

如果你希望反序列化直接得到可绑定的对象,可以自定义一个JSON转换器,自动把每个单键对象转换成包含设备ID的实体:

步骤1:创建显示实体和转换器

public class GpsDisplayItem {
    public string DeviceId { get; set; }
    public string Fecha { get; set; }
    public string Kilometros { get; set; }
    public string Odometro { get; set; }
    public string Horas { get; set; }
}

public class GpsItemConverter : JsonConverter<GpsDisplayItem> {
    public override GpsDisplayItem ReadJson(JsonReader reader, Type objectType, GpsDisplayItem existingValue, bool hasExistingValue, JsonSerializer serializer) {
        // 加载当前JSON对象
        var jObject = JObject.Load(reader);
        // 获取唯一的设备ID键
        var deviceId = jObject.Properties().First().Name;
        // 解析对应的GPS数据
        var odometroData = jObject.Properties().First().Value.ToObject<GpsOdometro>();
        
        return new GpsDisplayItem {
            DeviceId = deviceId,
            Fecha = odometroData.Fecha,
            Kilometros = odometroData.Kilometros,
            Odometro = odometroData.Odometro,
            Horas = odometroData.Horas
        };
    }

    public override void WriteJson(JsonWriter writer, GpsDisplayItem value, JsonSerializer serializer) {
        // 如果不需要序列化回去,可以留空或抛出异常
        throw new NotImplementedException();
    }
}

步骤2:调整RootObject并应用转换器

public class GpsOdometro {
    public string Fecha { get; set; }
    public string Kilometros { get; set; }
    public string Odometro { get; set; }
    public string Horas { get; set; }
}

public class RootObject {
    public int status { get; set; }
    // 对data字段应用自定义转换器
    [JsonConverter(typeof(GpsItemConverter))]
    public List<GpsDisplayItem> data { get; set; }
}

步骤3:反序列化并直接绑定

现在反序列化后可以直接把result.data绑定到DataGridView:

IRestResponse json = client.Execute(request);
RootObject result = JsonConvert.DeserializeObject<RootObject>(json.Content);
DgOdometro.DataSource = result.data;

两种方案都能解决你的问题,方案1更简单,方案2更优雅,适合后续扩展。

内容的提问来源于stack exchange,提问作者Limberg A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:49:37