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[] 三种格式
相关推荐
c1s2d3n4cs14 小时前
Qt模仿nlohmann::json进行序列化和反序列化
开发语言·qt·json
一只很酸de橘子15 小时前
PostgreSQL 生成 JSON 字符串
postgresql·json
Kiyra1 天前
Query Rewrite 不是越智能越好:RAG 检索的精确词保护与动态召回
redis·websocket·junit·单元测试·json
Msshu1231 天前
XSP25全协议 100W PD快充诱骗芯片_串口读电压电流信息
hive·云计算·json·database·memcached
水火既济__1 天前
hive中加载json数据建表(大规模)
hive·hadoop·json
朝新_1 天前
【LangChain】输出解析器 Str/Pydantic/JSON 解析器用法详解 告别模型乱输出
microsoft·langchain·json
Kiyra2 天前
LLM 的 JSON 不靠谱:结构化输出的重试与修复实战
开发语言·python·json
易生一世2 天前
JWT详解
json·证书·jwt·token·ai skills
原来是猿3 天前
JSON 序列化与反序列化 —— 用 Jsoncpp 打造自己的网络协议
网络·网络协议·json