You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用CSVHelper解析含JSON数据列的CSV文件遇到的问题

解决CSVHelper解析包含未转义JSON列的CSV文件问题

你的问题根源在于CSV文件中JSON字段的双引号未正确转义,导致CSVHelper无法识别整个JSON字符串为单个字段,进而将JSON内部的逗号误判为CSV分隔符。以下是两种可行的解决方法:


方案1:修复CSV格式(推荐)

如果可以控制CSV的生成逻辑,确保JSON字段内的双引号按CSV规范转义。标准CSV中,字段内的双引号需要用双引号重复转义,修正后的CSV内容如下:

id1,4000,"{""red"":""#f00"",""green"":""#0f0"",""blue"":""#00f""}",color_pattern1
id2,300,"{""magenta"":""#f0f"",""yellow"":""#ff0"",""black"":""#000""}",color_pattern2

或者使用反斜杠转义(需配合CSVHelper配置):

id1,4000,"{\"red\":\"#f00\",\"green\":\"#0f0\",\"blue\":\"#00f\"}",color_pattern1
id2,300,"{\"magenta\":\"#f0f\",\"yellow\":\"#ff0\",\"black\":\"#000\"}",color_pattern2

对应调整CSVHelper配置:

var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = false,
    // 若用反斜杠转义,需添加以下配置
    // Escape = '\\'
};

修改后你的原有解析代码即可正常工作,CSVHelper会自动识别完整的JSON字段。


方案2:自定义解析逻辑(无法修改CSV时)

如果无法调整CSV生成规则,可通过自定义逻辑手动识别JSON字段的边界。

方法A:逐行手动拆分字段

直接读取每行文本,根据引号和JSON结构拆分字段:

TextReader tr = new StreamReader(blobContent);
string line;
while ((line = tr.ReadLine()) != null)
{
    int firstQuote = line.IndexOf('"');
    int lastQuote = line.LastIndexOf('"');
    
    if (firstQuote == -1 || lastQuote == -1 || firstQuote >= lastQuote)
        continue;

    // 拆分四个字段
    int firstComma = line.IndexOf(',');
    int secondComma = line.IndexOf(',', firstComma + 1);
    int lastComma = line.IndexOf(',', lastQuote + 1);

    var record = new CSVData
    {
        Id = line.Substring(0, firstComma),
        Intensity = line.Substring(firstComma + 1, secondComma - firstComma - 1),
        JsonData = line.Substring(firstQuote + 1, lastQuote - firstQuote - 1),
        ColourPatternId = line.Substring(lastComma + 1)
    };

    Console.WriteLine($"JSON Data: {record.JsonData}");
    Console.WriteLine($" Colour Pattern ID: {record.ColourPatternId}");
}

方法B:自定义CSVHelper转换器

通过TypeConverter处理JSON字段的拼接:

public class JsonFieldConverter : StringConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        var sb = new StringBuilder(text);
        int braceCount = text.Count(c => c == '{') - text.Count(c => c == '}');
        
        // 持续读取字段直到JSON括号闭合
        while (braceCount > 0 && row.Parser.Read())
        {
            string nextField = row.Parser.Record[row.Parser.Index];
            sb.Append(",").Append(nextField);
            braceCount += nextField.Count(c => c == '{') - nextField.Count(c => c == '}');
        }
        
        return sb.ToString();
    }
}

在CSVData类的JsonData属性上绑定转换器:

public class CSVData
{
    [Index(0)]
    public string Id { get; set; }
    [Index(1)]
    public string Intensity { get; set; }
    [Index(2)]
    [TypeConverter(typeof(JsonFieldConverter))]
    public string JsonData { get; set; }
    [Index(3)]
    public string ColourPatternId { get; set; }
}

最后恢复CSVHelper配置(不要设置BadDataFound = null):

var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    HasHeaderRecord = false
};

using (var csv = new CsvReader(new StreamReader(blobContent), config))
{
    foreach (var r in csv.GetRecords<CSVData>())
    {
        Console.WriteLine($"JSON Data: {r.JsonData}");
        Console.WriteLine($" Colour Pattern ID: {r.ColourPatternId}");
    }
}

内容的提问来源于stack exchange,提问作者blank_stare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:35:29