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

使用CsvHelper的CsvDataReader时如何为空字符串指定默认int值

如何在使用CsvReader和CsvDataReader加载CSV到DataTable时,为空字符串的int列指定默认值0?

问题描述

我希望使用CsvReader和CsvDataReader将CSV数据加载到预定义列类型的DataTable中,但当CSV字段出现空字符串(比如连续的;;)时,int类型的列(例如Credits列)会解析失败,抛出类似Input string was not in a correct format.Couldn't store <> in Credits Column. Expected type is Int32的异常。请问如何在这种情况下给Credits列指定默认的int值0?

示例代码

// 构建DataTable
DataTable dataTable = new DataTable();
dataTable.Columns.Add(new DataColumn("Name", typeof(string)));
dataTable.Columns.Add(new DataColumn("Credits", typeof(int)));
dataTable.Columns.Add(new DataColumn("Notes", typeof(string)));
dataTable.Columns.Add(new DataColumn("LastLogin", typeof(DateTime)));
dataTable.Columns.Add(new DataColumn("Balance", typeof(decimal)));

// 准备CSV内容
StringBuilder sbInput = new StringBuilder();
sbInput.AppendLine("Name;Credits;Notes;LastLogin;Balance");
sbInput.AppendLine("Michael;2433;Good guy;2023-03-28;736,26");
sbInput.AppendLine("John;;Bad guy;2023-04-01;-49,25");

// 配置CsvReader
CsvConfiguration csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    NewLine = Environment.NewLine,
    Delimiter = ";",
    Mode = CsvMode.NoEscape,
    TrimOptions = TrimOptions.Trim,
    UseNewObjectForNullReferenceMembers = true
};

// 读取CSV流并加载到DataTable
using (var csvReader = new CsvReader(new StringReader(sbInput.ToString()), csvConfiguration))
{
    using (var csvDataReader = new CsvDataReader(csvReader))
    {
        // 当出现John;;Bad guy这样的行时会抛出异常
        // 异常信息:Input string was not in a correct format.Couldn't store <> in Credits Column.  Expected type is Int32.
        dataTable.Load(csvDataReader);
    }
}

解决方案

方法一:自定义CsvHelper类型转换器(全局生效)

通过自定义类型转换器,让CsvReader在解析int类型字段时,自动将空字符串转换为0。

  1. 定义自定义转换器类:
public class Int32WithDefaultConverter : DefaultTypeConverter
{
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        // 处理空或空白字符串,返回默认值0
        if (string.IsNullOrWhiteSpace(text))
        {
            return 0;
        }
        // 非空时按正常逻辑解析
        return int.Parse(text, memberMapData.TypeConverterOptions.CultureInfo);
    }
}
  1. 在Csv配置中注册该转换器:
CsvConfiguration csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    NewLine = Environment.NewLine,
    Delimiter = ";",
    Mode = CsvMode.NoEscape,
    TrimOptions = TrimOptions.Trim,
    UseNewObjectForNullReferenceMembers = true
};
// 为int类型注册自定义转换器
csvConfiguration.TypeConverterCache.AddConverter<int>(new Int32WithDefaultConverter());

修改后,CsvReader会自动将空的int字段解析为0,DataTable加载时不会再抛出异常。

方法二:监听DataTable的ColumnChanging事件(针对特定列)

如果只需要对单个列(比如Credits)设置默认值,可以通过DataTable的ColumnChanging事件处理:

// 在创建DataTable后添加事件监听
dataTable.ColumnChanging += (sender, e) =>
{
    // 仅针对Credits列,当值为DBNull时设置为0
    if (e.Column.ColumnName == "Credits" && e.ProposedValue == DBNull.Value)
    {
        e.ProposedValue = 0;
    }
};

这种方式更灵活,可针对特定列单独处理,但需要确保CsvDataReader将空字符串转换为DBNull.Value(默认配置下即可实现)。


内容的提问来源于stack exchange,提问作者Brøgger

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 22:39:53