我目前正在使用 CSV 帮助程序读取 csv 文件的内容并将其输出到控制台。我已经安装了 csvHelper nuget 包。但是,当我运行代码时,出现以下错误:
CsvHelper.TypeConversion.TypeConverterException: '无法执行转换。 文本: '' 成员(member)类型: TypeConverter: 'CsvHelper.TypeConversion.Int32Converter''
据我了解,这是由于 csv 中的字段人口为空所致。我目前希望能够验证该字段并将其设置为 0。如何使用 CSVhelper 执行此操作。
我读取 csv 的代码是:
class ReaderCsv
{
private string _cvsfilepath;
public ReaderCsv(string csvfilepath)
{
this._cvsfilepath = csvfilepath;
}
public List <Country> ReadAllCountries()
{
var countries = new List<Country>();
using (var sr = new StreamReader(_cvsfilepath))
using (var csv = new CsvReader(sr, System.Globalization.CultureInfo.InvariantCulture))
{
csv.Configuration.Delimiter = ",";
csv.Read();
csv.ReadHeader();
while (csv.Read())
{
var country= new Country();
{
country.CountryName = csv.GetField("CountryName");
country.CountryCode = csv.GetField("CountryCode");
country.Continent = csv.GetField("CountryCode");
country.Population = csv.GetField<int>("Population");
}
countries.Add(country);
}
}return countries;
}
}
}
我的映射类是
public class CountryMap : ClassMap<Country>
{
public CountryMap()
{
Map(m => m.CountryName);
Map(m => m.CountryCode);
Map(m => m.Continent);
Map(m => m.Population);
}
}
最佳答案
CSV Helper 提供了 GetField 方法的重载,您可以将自定义类型转换器传递给该方法。
https://joshclose.github.io/CsvHelper/api/CsvHelper/CsvReader/
因此;不仅适用于 Int32,而且适用于任何类型,这是一个使用自定义泛型类型转换器的实现,如果转换失败,该转换器将返回该类型的默认值。
这并不意味着您必须吞下或忽略异常。此转换器还会为您提供转换错误和违规值,以便您可以处理此无效数据。
我还添加了一个 lineNumber 变量来跟踪无效数据所在的行。
希望对您有所帮助。
public class Defaulter<T> : CsvHelper.TypeConversion.ITypeConverter
{
Exception conversionError;
string offendingValue;
public Exception GetLastError()
{
return conversionError;
}
public string GetOffendingValue()
{
return offendingValue;
}
object CsvHelper.TypeConversion.ITypeConverter.ConvertFromString(string text, IReaderRow row, CsvHelper.Configuration.MemberMapData memberMapData)
{
conversionError = null;
offendingValue = null;
try
{
return (T)Convert.ChangeType(text, typeof(T));
}
catch (Exception localConversionError)
{
conversionError = localConversionError;
}
return default(T);
}
string CsvHelper.TypeConversion.ITypeConverter.ConvertToString(object value, IWriterRow row, CsvHelper.Configuration.MemberMapData memberMapData)
{
return Convert.ToString(value);
}
}
这里是您的代码的修改版本,用于跟踪行号以及根据需要处理错误:
public class ReaderCsv
{
private string _cvsfilepath;
public ReaderCsv(string csvfilepath)
{
this._cvsfilepath = csvfilepath;
}
public List<Country> ReadAllCountries()
{
var countries = new List<Country>();
using (var sr = new StreamReader(_cvsfilepath))
using (var csv = new CsvReader(sr, System.Globalization.CultureInfo.InvariantCulture))
{
csv.Configuration.Delimiter = ",";
csv.Read();
csv.ReadHeader();
Defaulter<int> customInt32Converter = new Defaulter<int>();
int lineNumber = 0;
while (csv.Read())
{
lineNumber++;
var country = new Country();
{
country.CountryName = csv.GetField("CountryName");
country.CountryCode = csv.GetField("CountryCode");
country.Continent = csv.GetField("CountryCode");
country.Population = csv.GetField<int>("Population", customInt32Converter);
if (customInt32Converter.GetLastError() != null)
{
// The last conversion has failed.
// Handle it here.
string errorMessage = "The conversion of Population field on line " + lineNumber + " has failed. The Population value was: [" + customInt32Converter.GetOffendingValue() + "]";
}
}
countries.Add(country);
}
}
return countries;
}
}
问候。
关于c# - 使用 csvHelper 处理 csv 文件中的无效条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60762144/