JSON 里是一个空字符串 ““,Newtonsoft.Json 无法直接把字符串转成列表

在一个自动任务中,没有做好错误判断,导致程序出错错误代码:

cs 复制代码
Newtonsoft.Json.JsonSerializationException: Error converting value "" to type 'System.Collections.Generic.List`1[Auto_MeiLi.OrderHaveDoneItem]'. ---> System.Exception: Could not cast or convert from System.String to System.Collections.Generic.List`1[Auto_MeiLi.OrderHaveDoneItem].
   在 Newtonsoft.Json.Utilities.ConvertUtils.EnsureTypeAssignable(Object value, Type initialType, Type targetType)
   在 Newtonsoft.Json.Utilities.ConvertUtils.ConvertOrCast(Object initialValue, CultureInfo culture, Type targetType)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(Object value, CultureInfo culture, Type targetType)
   --- 内部异常堆栈跟踪的结尾 ---
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(Object value, CultureInfo culture, Type targetType)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueProperty(JsonReader reader, JsonProperty property, Object target, Boolean gottenCurrentValue, Object currentValue)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonReader reader, Object target)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, String id)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateObject(JsonReader reader, JsonObjectContract contract, String id)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract)
   在 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType)
   在 Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
   在 Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings)
   在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
   在 Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
   在 Auto_MeiLi.Auto_MeiLi.GetFidList()
   在 Auto_MeiLi.Auto_MeiLi.ExecuteAllTasksAsync()
   在 Auto_MeiLi.Auto_MeiLi.Timer_Elapsed(Object sender, ElapsedEventArgs e)

解决方式:

问题原因 + 完整解决方案

这个错误的核心原因:你的 JSON 里是一个空字符串 "",但 C# 类里定义的是 List<OrderHaveDoneItem> 集合类型,Newtonsoft.Json 无法直接把字符串转成列表,所以抛出序列化异常。

错误场景还原

  1. C# 实体类定义(错误写法)

csharp

运行

复制代码
public class 你的类名
{
    // 这里定义的是列表
    public List<OrderHaveDoneItem> OrderHaveDoneItems { get; set; } 
}
  1. 实际 JSON 数据(不匹配)

json

复制代码
{
  "OrderHaveDoneItems": ""  // 后端/接口返回了空字符串,不是数组 []
}

最优解决方案(自定义 Json 转换器)

直接写一个通用的字符串转列表转换器,遇到空字符串自动返回空列表,完美兼容异常数据。

步骤 1:创建转换器

csharp

运行

复制代码
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;

/// <summary>
/// 处理JSON字符串自动转换为List<T>的转换器
/// 空字符串/无效值 → 自动转为空列表,不抛异常
/// </summary>
public class StringToListConverter<T> : JsonConverter<List<T>>
{
    public override void WriteJson(JsonWriter writer, List<T> value, JsonSerializer serializer)
    {
        // 序列化:正常写入数组
        serializer.Serialize(writer, value);
    }

    public override List<T> ReadJson(JsonReader reader, Type objectType, List<T> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 读取值
        var value = reader.Value;

        // 情况1:值是null/空字符串 → 返回空列表
        if (value == null || string.IsNullOrWhiteSpace(value.ToString()))
        {
            return new List<T>();
        }

        // 情况2:值是字符串格式的数组(如"[{},{}]")→ 反序列化
        var str = value.ToString();
        if (str.StartsWith("[") && str.EndsWith("]"))
        {
            return JsonConvert.DeserializeObject<List<T>>(str);
        }

        // 默认:返回空列表
        return new List<T>();
    }
}

步骤 2:给实体类属性打上标签

csharp

运行

复制代码
public class 你的类名
{
    // 加上这个特性即可
    [JsonConverter(typeof(StringToListConverter<OrderHaveDoneItem>))]
    public List<OrderHaveDoneItem> OrderHaveDoneItems { get; set; }
}

步骤 3:正常反序列化(无需修改原有代码)

csharp

运行

复制代码
var result = JsonConvert.DeserializeObject<你的类名>(json字符串);

简易方案(无需转换器,快速修复)

如果不想写转换器,直接在反序列化时处理

csharp

运行

复制代码
// 原始代码(报错)
// var list = JsonConvert.DeserializeObject<List<OrderHaveDoneItem>>(json);

// 修复后代码
List<OrderHaveDoneItem> list;
if (string.IsNullOrWhiteSpace(json) || json == "\"\"")
{
    list = new List<OrderHaveDoneItem>(); // 空字符串 → 空列表
}
else
{
    list = JsonConvert.DeserializeObject<List<OrderHaveDoneItem>>(json);
}

根本原因总结

  1. C# 类型:List<OrderHaveDoneItem>(期望是 JSON 数组 []
  2. JSON 数据:""(空字符串,类型不匹配)
  3. Newtonsoft.Json 不支持字符串 → 集合的自动转换

最终效果

  • JSON 为 "" → 自动转为 空List,不报错
  • JSON 为 [] / [{"Id":1},{"Id":2}] → 正常解析
  • 完全兼容接口返回的异常数据

总结

  1. 核心问题:空字符串无法直接转换为 List 集合
  2. 推荐方案:使用自定义 Json 转换器,一劳永逸解决所有同类问题
  3. 快速方案:判断空字符串,手动返回空列表
  4. 修复后,你的代码可以直接兼容接口返回的 ""null[] 三种格式
相关推荐
疯狂SQL3 天前
手写高性能在线 JSON 工具|Web Worker 工程化打包 + 语法自动修复 + 多语言代码生成实战
typescript·json·next.js·web worker·前端性能优化·esbuild·源码实战
terry6008 天前
5G视频短信服务商选型全攻略:通道资源、架构能力与成本评估2026最新标准
大数据·人工智能·5g·json·asp.net·信息与通信·数据库架构
前网易架构师-高司机8 天前
带标注的辣椒病叶数据集,识别率95.9%,可识别三种病害和健康叶子,9916张图,支持yolo,coco json,voc xml,文末有模型训练代码
yolo·json·数据集·病害·叶病·病叶·辣椒
PixelBai8 天前
JSON扁平化使用教程:从入门到精通
json
渔舟唱晚,雁阵惊寒9 天前
CSDN博客内容丢失如何恢复?
json
衣乌安、9 天前
JSON-RPC协议
网络协议·rpc·json
PixelBai9 天前
JSON过滤使用教程:从入门到精通
javascript·chrome·json
PixelBai9 天前
JSON过滤实际应用场景案例
json
一生了无挂9 天前
Java处理JSON技巧教学(从基础到高阶实战全覆盖)
java·开发语言·json