如何解析CSV中包含JSON内容的列并反序列化为C#自定义对象
你遇到的问题本质是手动按逗号拆分CSV不符合CSV标准格式解析规则:Excel导出的带引号包裹的JSON字段中,逗号是字段内容而非分隔符,同时字段内的双引号被Excel转义为连续两个双引号,手动拆分无法处理这两个场景。以下是两种可直接落地的实现方案:
方案1:使用CsvHelper(推荐,无需自行处理格式兼容)
CsvHelper是专门处理CSV格式的开源库,会自动兼容RFC 4180标准的CSV转义规则。
- 首先通过NuGet安装
CsvHelper包 - 补全类定义(你之前的Request类缺失了Id、Name属性):
public class Friend { public int id { get; set; } public string name { get; set; } } public class Request { // 补全CSV前两列对应的属性 public string Id { get; set; } public string Name { get; set; } public double latitude { get; set; } public double longitude { get; set; } public List<string> tags { get; set; } public List<Friend> friends { get; set; } public string greeting { get; set; } public string favoriteFruit { get; set; } } // CSV行映射临时类 public class CsvRow { public string Id { get; set; } public string Name { get; set; } public string requestJson { get; set; } }
- 解析代码实现:
using CsvHelper; using CsvHelper.Configuration; using System.Globalization; using Newtonsoft.Json; public static List<Request> LoadFiles() { var config = new CsvConfiguration(CultureInfo.InvariantCulture) { AllowComments = false, TrimOptions = TrimOptions.None }; using var reader = new StreamReader("./example.csv"); using var csv = new CsvReader(reader, config); var rows = csv.GetRecords<CsvRow>().ToList(); // 转换为目标对象 return rows.Select(row => { var request = JsonConvert.DeserializeObject<Request>(row.requestJson); request.Id = row.Id; request.Name = row.Name; return request; }).ToList(); }
CsvHelper会自动处理引号包裹的字段,自动把字段内的连续双引号转义为单个双引号,拿到的requestJson直接就是合法JSON可直接反序列化。
方案2:使用.NET自带TextFieldParser(无需引入第三方库)
如果你不想额外安装NuGet包,可以使用.NET框架自带的TextFieldParser(需要引用Microsoft.VisualBasic程序集,C#项目可正常使用):
using Microsoft.VisualBasic.FileIO; using Newtonsoft.Json; public static List<Request> LoadFiles() { var requests = new List<Request>(); using (var parser = new TextFieldParser("./example.csv")) { parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); parser.HasFieldsEnclosedInQuotes = true; // 跳过表头 parser.ReadLine(); while (!parser.EndOfData) { string[] fields = parser.ReadFields(); if (fields == null || fields.Length < 3) continue; var request = JsonConvert.DeserializeObject<Request>(fields[2]); request.Id = fields[0]; request.Name = fields[1]; requests.Add(request); } } return requests; }
该方案同样会自动处理CSV的引号包裹和转义规则,无需手动做字符串替换。
不推荐自行实现CSV拆分逻辑:需要处理引号开闭状态判断、转义字符替换等大量边界场景,容错率极低,极易出现解析错误。
内容的提问来源于stack exchange,提问作者supernovascotia
相关产品推荐
相关产品推荐

