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

.NET中JsonConvert兼容Survey数据单对象/数组反序列化的解决

解决API返回单条/多条/零条Survey数据的JSON反序列化兼容问题

问题根源是API返回的Response节点类型不统一:多条数据时为数组,单条时为单个对象,零条时可能无节点或为null,导致Newtonsoft.Json无法直接适配数组类型的属性。以下是最可靠的解决方案:

方案1:自定义JsonConverter统一处理对象/数组转换

步骤1:实现SingleOrArrayConverter转换器

这个转换器会自动将单个对象包装为数组,数组直接保留,空值/无节点返回空数组:

public class SingleOrArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(T[]) || objectType == typeof(List<T>);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var tokenType = reader.TokenType;
        
        switch (tokenType)
        {
            case JsonToken.StartArray:
                return serializer.Deserialize<T[]>(reader);
            case JsonToken.StartObject:
                var singleItem = serializer.Deserialize<T>(reader);
                return new T[] { singleItem };
            case JsonToken.Null:
            case JsonToken.Undefined:
                return Array.Empty<T>();
            default:
                throw new JsonSerializationException($"无法处理的Token类型:{tokenType}");
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 如需序列化时自动适配(单条写对象,多条写数组),可保留此方法;仅反序列化的话也可留空
        var array = value as T[];
        if (array?.Length == 1)
        {
            serializer.Serialize(writer, array[0]);
        }
        else
        {
            serializer.Serialize(writer, value);
        }
    }
}

步骤2:修改实体类并添加转换器特性

同时修正JSON键名匹配问题(原JSON中的"?xml"和"@version"需要用JsonProperty特性映射):

public class SurveyJsonModel
{
    public class Rootobject
    {
        [JsonProperty("?xml")]
        public Xml Xml { get; set; }
        public Responses Responses { get; set; }
    }

    public class Xml
    {
        [JsonProperty("@version")]
        public string Version { get; set; }
    }

    public class Responses
    {
        [JsonConverter(typeof(SingleOrArrayConverter<Response>))]
        public Response[] Response { get; set; }
    }

    public class Response
    {
        public string startDate { get; set; }
        public string endDate { get; set; }
        public string status { get; set; }
        public string ipAddress { get; set; }
    }
}

步骤3:正常使用反序列化代码

无需修改原有反序列化逻辑,直接调用即可兼容三种场景:

var surveyData = JsonConvert.DeserializeObject<SurveyJsonModel.Rootobject>(json);

兼容场景说明

  • 多条数据:Response为数组时,转换器直接反序列化为数组
  • 单条数据:Response为单个对象时,转换器自动包装为单元素数组
  • 零条数据:Response节点不存在、为null或空数组时,返回Array.Empty<Response>(),避免空引用异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:10:27