CSV Helper предоставляет перегрузки метода GetField, в который можно передать пользовательский преобразователь типов.
https://joshclose.github.io/CsvHelper/api/CsvHelper/CsvReader/
Следовательно; и не только для Int32, но и для любого типа, здесь есть реализация, использующая пользовательский преобразователь типа generi c, который возвращает значение по умолчанию для типа в случае сбоя преобразования.
Это не означает, что вы должны проглотить или игнорировать исключение. Этот преобразователь также выдаст вам ошибку преобразования и ошибочное значение, чтобы вы могли обработать эти недопустимые данные.
Я также добавил переменную 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;
}
}
С уважением.