如何使用System.Runtime.Serialization.Json将JSON数组反序列化为List?我的实现正确吗?
问题分析与解决方案
你的反序列化失败主要源于JSON根结构不匹配和数据成员名称映射错误两个核心问题,咱们一步步拆解解决:
1. 核心问题点梳理
(1)JSON根结构不匹配
你的JSON数据根是一个包含assignments数组的对象:
{ "assignments":[...] }
但你的ReadJsonFile1方法直接尝试反序列化为List<T>,相当于告诉序列化器「JSON内容应该是一个纯数组」,但实际根是对象,结构不匹配自然会失败。
(2)DataMember名称映射错误
CourseWork类中Assignment属性的DataMember标记的是"assignmentname",但JSON里对应的键是"assignments",名称不匹配会导致序列化器无法正确识别并赋值。
2. 修正后的解决方案
方案一:贴合现有JSON结构,直接反序列化到CourseWork对象
这是最适配你当前代码设计的方案:
第一步:修正CourseWork类的DataMember名称
public class CourseWork { private List<Assignment> assignments; // 把Name改成和JSON键一致的"assignments" [DataMember(Name = "assignments")] public List<Assignment> Assignment { get { return assignments; } set { assignments = value; } } public CourseWork() { assignments = new List<Assignment>(); } }
第二步:优化反序列化方法(加入资源自动释放)
T ReadJsonFile<T>() where T : new() { Console.Write("Enter Json File Name: "); string fileName = Console.ReadLine(); // 使用using语句自动释放文件流,避免内存泄漏 using (FileStream reader = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { DataContractJsonSerializer deser = new DataContractJsonSerializer(typeof(T)); return (T)deser.ReadObject(reader); } }
第三步:Main方法中调用
CourseWork cw = ReadJsonFile<CourseWork>(); // 此时cw.Assignment已正确加载JSON中的Assignment列表
方案二:直接反序列化List(可选)
如果想跳过外层对象直接获取数组,需要手动解析JSON提取数组部分:
List<Assignment> ReadAssignmentsFromJson() { Console.Write("Enter Json File Name: "); string fileName = Console.ReadLine(); using (FileStream reader = new FileStream(fileName, FileMode.Open, FileAccess.Read)) using (StreamReader sr = new StreamReader(reader)) { string json = sr.ReadToEnd(); // 先解析外层对象,提取assignments数组 var temp = new System.Web.Script.Serialization.JavaScriptSerializer() .Deserialize<dynamic>(json); // 再将数组反序列化为List<Assignment> return new System.Web.Script.Serialization.JavaScriptSerializer() .Deserialize<List<Assignment>>(temp["assignments"].ToString()); } }
小提示
你的Assignment类构造函数里的"defaut"是拼写错误,应该是"default",虽然不影响反序列化,但建议修正避免歧义。
内容的提问来源于stack exchange,提问作者ChowShow
相关产品推荐
相关产品推荐

