CSVHelper从2.7.1升级至30版本后异常处理问题咨询
CSVHelper从2.7.1升级到30版本后的异常处理问题
将CSVHelper库从2.7.1版本升级至30版本,已解决所有编译错误,但升级后异常无法正常记录。以下是新旧版本的异常处理代码:
旧版本(2.7.1)代码
csvReader.Configuration.ReadingExceptionCallback = (ex, row) => { if (ex is CsvHelper.TypeConversion.CsvTypeConverterException) { foreach (DictionaryEntry error in ex.Data) { AddRowError(row.Row, error.Value.ToString() + " Column Name: '" + GetColumnName(row) + "'"); } } else if (ex is FormatException) { AddRowError(row.Row, ex.Message + " Column Name: '" + GetColumnName(row) + "' Column Value: '" + GetColumnValue(row) + "'"); } else { AddRowError(row.Row, string.Format("Line[{0}]: {1}", row.Row, ex.StackTrace)); } };
新版本(30)代码
ReadingExceptionOccurred = args => { var context = args.Exception.Context; if (args.Exception is CsvHelper.TypeConversion.TypeConverterException) { foreach (DictionaryEntry error in args.Exception.Data) { AddRowError(context.Parser.Row, error.Value.ToString() + " Column Name: '" + GetColumnName(context.Reader) + "'"); } } else if (args.Exception.GetType() == typeof(FormatException)) { AddRowError(context.Parser.Row, args.Exception.Message + " Column Name: '" + GetColumnName(context.Reader) + "' Column Value: '" + GetColumnValue(context.Reader) + "'"); } else { AddRowError(context.Parser.Row, string.Format("Line[{0}]: {1}", context.Parser.Row, args.Exception.StackTrace)); } return false; },
现存问题
- 无法从
args.Exception.Data获取旧版本中的键值对; - 无法正确处理
FormatException的内容;
解决方案
1. 处理类型转换异常的错误数据
CSVHelper 30版本中,TypeConverterException不再通过Data字典存储错误信息,而是直接将关键信息包含在异常Message中,同时可以通过args.Context获取当前列的上下文信息来构造完整错误内容:
替换原类型转换异常处理代码为:
if (args.Exception is CsvHelper.TypeConversion.TypeConverterException typeEx) { var currentColumnIndex = args.Context.Reader.Context.CurrentIndex; var columnName = args.Context.Reader.HeaderRecord[currentColumnIndex]; var errorMessage = $"{typeEx.Message} Column Name: '{columnName}'"; AddRowError(args.Context.Parser.Row, errorMessage); }
如果需要获取当前列的具体值,可添加:
var columnValue = args.Context.Reader.GetField(currentColumnIndex);
2. 正确处理FormatException
新版本中FormatException多在解析基础数据类型时抛出,直接通过args.Context.Reader获取当前列的名称和值即可:
替换原FormatException处理代码为:
else if (args.Exception is FormatException formatEx) { var currentColumnIndex = args.Context.Reader.Context.CurrentIndex; var columnName = args.Context.Reader.HeaderRecord[currentColumnIndex]; var columnValue = args.Context.Reader.GetField(currentColumnIndex); var errorMessage = $"{formatEx.Message} Column Name: '{columnName}' Column Value: '{columnValue}'"; AddRowError(args.Context.Parser.Row, errorMessage); }
完整修改后的异常处理代码
ReadingExceptionOccurred = args => { var rowNumber = args.Context.Parser.Row; if (args.Exception is CsvHelper.TypeConversion.TypeConverterException typeEx) { var currentColumnIndex = args.Context.Reader.Context.CurrentIndex; var columnName = args.Context.Reader.HeaderRecord[currentColumnIndex]; var errorMessage = $"{typeEx.Message} Column Name: '{columnName}'"; AddRowError(rowNumber, errorMessage); } else if (args.Exception is FormatException formatEx) { var currentColumnIndex = args.Context.Reader.Context.CurrentIndex; var columnName = args.Context.Reader.HeaderRecord[currentColumnIndex]; var columnValue = args.Context.Reader.GetField(currentColumnIndex); var errorMessage = $"{formatEx.Message} Column Name: '{columnName}' Column Value: '{columnValue}'"; AddRowError(rowNumber, errorMessage); } else { var errorMessage = $"Line[{rowNumber}]: {args.Exception.StackTrace}"; AddRowError(rowNumber, errorMessage); } return false; },
内容的提问来源于stack exchange,提问作者user768853
相关产品推荐
相关产品推荐

