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

如何用CsvHelper写入未转义带引号值?配置疑问求助

CsvHelper如何写入未转义的带引号值?

问题场景

原始输入CSV内容:

Jake|"B" Street

通过以下读取配置,已成功读取到未转义的字段值"B" Street:

var readerConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    Delimiter = "|",
    TrimOptions = TrimOptions.Trim,     
    IgnoreBlankLines = true,
    Mode = CsvMode.NoEscape
};

但写入CSV时遇到两难情况:

  • 不设置CsvMode.NoEscape,仅开启ShouldQuote = args => true:输出为"""B"" Street"(字段内双引号被转义)
  • 设置CsvMode.NoEscape且开启ShouldQuote = args => true:输出不带引号,仅为"B" Street

当前使用的写入配置:

writerConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    ShouldQuote = args => true,
    Mode = CsvMode.NoEscape
};

解决方案

要实现带引号包裹且字段内双引号不转义的目标,核心是手动控制引号的添加,结合CsvMode.NoEscape禁用转义逻辑:

方法1:手动处理字段输出

关闭自动引号功能,在写入时为目标字段手动添加引号:

var writerConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    Delimiter = "|",
    Mode = CsvMode.NoEscape,
    ShouldQuote = args => false // 禁用自动引号处理
};

using (var writer = new CsvWriter(yourTextWriter, writerConfig))
{
    foreach (var record in yourRecords)
    {
        writer.WriteField(record.Name);
        // 手动给需要带引号的字段添加双引号
        writer.WriteField($"\"{record.Street}\"");
        writer.NextRecord();
    }
}

方法2:自定义类型转换器(更优雅)

针对需要特殊处理的字段,自定义转换器来添加引号,同时保持配置简洁:

  1. 定义转换器:
public class UnescapedQuoteConverter : StringConverter
{
    public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
    {
        var strValue = value as string;
        return strValue != null ? $"\"{strValue}\"" : base.ConvertToString(value, row, memberMapData);
    }
}
  1. 配置字段映射:
public sealed class RecordMap : ClassMap<YourRecordType>
{
    public RecordMap()
    {
        Map(m => m.Name);
        // 为目标字段应用自定义转换器
        Map(m => m.Street).TypeConverter<UnescapedQuoteConverter>();
    }
}
  1. 写入配置及执行:
var writerConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    Delimiter = "|",
    Mode = CsvMode.NoEscape,
    ShouldQuote = args => false
};

using (var writer = new CsvWriter(yourTextWriter, writerConfig))
{
    writer.Context.RegisterClassMap<RecordMap>();
    writer.WriteRecords(yourRecords);
}

核心逻辑说明

CsvMode.NoEscape会完全禁用CsvHelper的转义处理,但同时也会关闭自动引号包裹的逻辑。因此不能依赖ShouldQuote来自动添加引号,必须通过手动拼接或自定义转换器的方式,主动为字段添加外层引号,从而得到Jake|"B" Street的预期输出。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 04:54:33