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

C#如何将键名为整数的JSON对象反序列化为数组

解决方案

不需要为0-5每个继电器单独定义冗余属性,通过自定义JSON转换器将动态数字键名的对象节点直接映射为固定长度数组,即可实现relayStatus[4]形式的索引访问效果。

第一步:定义精简版实体类

按照目标访问逻辑定义结构,去掉硬编码的Relay4这类冗余属性,可根据需要添加顶层快捷访问属性:

// 适用于.NET内置System.Text.Json,用Newtonsoft.Json的话把[JsonPropertyName]换成[JsonProperty]即可
public class DeviceData
{
    [JsonPropertyName("slot")]
    public int Slot { get; set; }
    [JsonPropertyName("io")]
    public IoInfo Io { get; set; }
    // 顶层快捷访问,直接用data.RelayStatus[4]即可取值
    public int[] RelayStatus => Io?.RelayStatusArray ?? new int[6];
}

public class IoInfo
{
    [JsonPropertyName("relay")]
    [JsonConverter(typeof(RelayArrayConverter))]
    public int[] RelayStatusArray { get; set; } = new int[6]; // 固定长度6,索引对应0-5继电器编号
}

// 内部辅助类,用于匹配单个继电器的JSON结构
internal class SingleRelay
{
    [JsonPropertyName("relayStatus")]
    public int Status { get; set; }
}

第二步:实现自定义JSON转换器

.NET 5+/Core 内置System.Text.Json 版本

public class RelayArrayConverter : JsonConverter<int[]>
{
    public override int[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var relayStatusArray = new int[6];
        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException("Relay节点格式非法,预期为对象类型");

        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject)
                return relayStatusArray;
            if (reader.TokenType != JsonTokenType.PropertyName)
                throw new JsonException("读取继电器编号失败");
            
            string keyName = reader.GetString()!;
            // 键名不是合法0-5数字的直接跳过
            if (!int.TryParse(keyName, out int relayIndex) || relayIndex < 0 || relayIndex > 5)
            {
                reader.Skip();
                continue;
            }

            reader.Read();
            var relayData = JsonSerializer.Deserialize<SingleRelay>(ref reader, options);
            relayStatusArray[relayIndex] = relayData.Status;
        }
        return relayStatusArray;
    }

    public override void Write(Utf8JsonWriter writer, int[] value, JsonSerializerOptions options)
    {
        writer.WriteStartObject();
        for (int i = 0; i < value.Length; i++)
        {
            writer.WritePropertyName(i.ToString());
            writer.WriteStartObject();
            writer.WriteNumber("relayStatus", value[i]);
            writer.WriteEndObject();
        }
        writer.WriteEndObject();
    }
}

Newtonsoft.Json(Json.NET) 版本

逻辑完全一致,仅适配库的API差异:

public class RelayArrayConverter : JsonConverter<int[]>
{
    public override int[] ReadJson(JsonReader reader, Type objectType, int[] existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var relayStatusArray = new int[6];
        var relayRoot = JObject.Load(reader);
        foreach (var prop in relayRoot.Properties())
        {
            if (!int.TryParse(prop.Name, out int relayIndex) || relayIndex <0 || relayIndex>5)
                continue;
            relayStatusArray[relayIndex] = prop.Value["relayStatus"]?.Value<int>() ?? 0;
        }
        return relayStatusArray;
    }

    public override void WriteJson(JsonWriter writer, int[] value, JsonSerializer serializer)
    {
        writer.WriteStartObject();
        for (int i = 0; i < value.Length; i++)
        {
            writer.WritePropertyName(i.ToString());
            writer.WriteStartObject();
            writer.WritePropertyName("relayStatus");
            writer.WriteValue(value[i]);
            writer.WriteEndObject();
        }
        writer.WriteEndObject();
    }

    public override bool CanWrite => true;
}

调用方式

反序列化后直接按索引访问即可:

// System.Text.Json 调用
var device = JsonSerializer.Deserialize<DeviceData>(jsonText);
int relay4Status = device.RelayStatus[4]; // 直接拿到示例里的1

// Newtonsoft.Json 调用
// var device = JsonConvert.DeserializeObject<DeviceData>(jsonText);
  • 数组默认长度为6,缺失的继电器编号对应位置默认值为0,可根据业务需求调整默认值
  • 内置非法键名过滤逻辑,遇到超出0-5范围的编号不会抛出异常
  • 转换器同时支持序列化,将对象转回JSON时会自动还原成原结构,不会破坏接口约定的JSON格式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:54:21