.NET Core中如何读取含唯一父元素的JSON文件并转为扁平数组
如何在.NET中读取含唯一父元素的JSON并转为扁平数组
问题场景
你遇到的JSON结构中,根节点是一组以唯一包名为键的键值对,每个键对应一个许可证信息对象。直接用数组类型反序列化会返回空结果,在线工具还会为每个唯一键生成单独类,这显然不实用,目标是将其转换为包含包名和所有许可证信息的扁平数组。
解决步骤
1. 用Dictionary<string, T>匹配JSON结构
由于JSON根节点是键值对格式,我们可以用Dictionary<string, NmpLicense>作为反序列化目标类型:string对应唯一的包名键,NmpLicense对应你已定义的许可证信息类。
2. 将字典转为扁平数组
通过LINQ将字典的键值对转换为包含包名的扁平列表,可选择扩展现有类或创建新类存储完整信息。
代码实现
定义扩展模型(推荐)
为了把包名纳入结果,创建强类型类:
public class PackageLicense { public string PackageName { get; set; } public string Licenses { get; set; } public string Repository { get; set; } public string Publisher { get; set; } public string Email { get; set; } public string Path { get; set; } public string LicenseFile { get; set; } }
修改读取方法
更新读取逻辑,先反序列化为字典,再转换为扁平数组:
public static async Task<List<PackageLicense>> ReadPackageLicensesAsync(string filePath) { try { using FileStream stream = File.OpenRead(filePath); // 反序列化解析唯一键与对应许可证信息 var licenseDictionary = await JsonSerializer.DeserializeAsync<Dictionary<string, NmpLicense>>(stream); // 转换为包含包名的扁平列表 return licenseDictionary? .Select(kv => new PackageLicense { PackageName = kv.Key, Licenses = kv.Value.licenses, Repository = kv.Value.repository, Publisher = kv.Value.publisher, Email = kv.Value.email, Path = kv.Value.path, LicenseFile = kv.Value.licenseFile }) .ToList() ?? new List<PackageLicense>(); } catch (JsonException ex) { // 根据需求添加错误处理(如日志) throw; } }
原代码问题说明
你之前的代码试图将JSON反序列化为数组类型,但JSON根节点是对象而非数组,因此返回空结果。使用Dictionary<string, NmpLicense>能正确匹配键值对结构,再通过LINQ转换即可得到期望的扁平数组。
简化方案(无需新类)
如果不需要强类型,也可以直接返回匿名类型列表:
public static async Task<List<object>> ReadFlatLicensesAsync(string filePath) { try { using FileStream stream = File.OpenRead(filePath); var licenseDictionary = await JsonSerializer.DeserializeAsync<Dictionary<string, NmpLicense>>(stream); return licenseDictionary? .Select(kv => new { PackageName = kv.Key, kv.Value.licenses, kv.Value.repository, kv.Value.publisher, kv.Value.email, kv.Value.path, kv.Value.licenseFile }) .Cast<object>() .ToList() ?? new List<object>(); } catch (JsonException ex) { throw; } }
内容的提问来源于stack exchange,提问作者Patola
相关产品推荐
相关产品推荐

