在一个自动任务中,没有做好错误判断,导致程序出错错误代码:
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 无法直接把字符串转成列表,所以抛出序列化异常。
错误场景还原
- C# 实体类定义(错误写法)
csharp
运行
public class 你的类名
{
// 这里定义的是列表
public List<OrderHaveDoneItem> OrderHaveDoneItems { get; set; }
}
- 实际 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);
}
根本原因总结
- C# 类型:
List<OrderHaveDoneItem>(期望是 JSON 数组[]) - JSON 数据:
""(空字符串,类型不匹配) - Newtonsoft.Json 不支持字符串 → 集合的自动转换
最终效果
- JSON 为
""→ 自动转为空List,不报错 - JSON 为
[]/[{"Id":1},{"Id":2}]→ 正常解析 - 完全兼容接口返回的异常数据
总结
- 核心问题:空字符串无法直接转换为 List 集合
- 推荐方案:使用自定义 Json 转换器,一劳永逸解决所有同类问题
- 快速方案:判断空字符串,手动返回空列表
- 修复后,你的代码可以直接兼容接口返回的
""、null、[]三种格式