【问题标题】:In CsvHelper how to catch a conversion error and know what field and what row it happened in?在 CsvHelper 中如何捕获转换错误并知道它发生在哪个字段和哪一行?
【发布时间】:2014-02-06 17:03:33
【问题描述】:

我成功地使用了CsvReader 类并且对它很满意,但是,我使用的文件是由一个更改列格式的组生成的,而不通知我。

所以,前一刻一切正常,然后第二天早上事情就中断了,csv.GetRecord<MyType>() 周围的 try catch 块捕获了错误并记录了错误,但是我无法从 Exception 实例中收集任何有价值的信息。它只是说:“无法执行转换。”而InnerException 什么都没有。不是很有用。我什至不知道我的 150 列中的哪一列导致了问题。

您能帮我弄清楚如何查明是哪一行中的哪一列导致了问题吗?

谢谢

【问题讨论】:

    标签: csvhelper


    【解决方案1】:

    目前,无法忽略字段/属性级别的错误。您当前的选择是:

    查看异常数据。

    catch( Exception ex )
    {
        // This contains useful information about the error.
        ex.Data["CsvHelper"];
    }
    

    忽略读取异常。但是,这是在行级别上,而不是在字段上。它将允许仍然读取整个文件,并忽略不起作用的行。发生异常时可以得到回调。

    csv.Configuration.IgnoreReadingExceptions = true;
    csv.Configuration.ReadingExceptionCallback = ( ex, row ) =>
    {
        // Do something with the exception and row data.
        // You can look at the exception data here too.
    };
    

    【讨论】:

      【解决方案2】:

      首先,看来我需要捕获 CsvTypeConverterException。

       while (csv.Read())
          {
             try
             {    
                var record = csv.GetRecord<MyType>();    
             }
             catch (CsvTypeConverterException ex)
             {
               //ex.Data.Values has more info...
             }
          }
      

      我现在知道如何调查出了什么问题,但我如何确保跳​​过该字段但该行中的其余字段已转换,从而不会丢弃整行?

      谢谢

      【讨论】:

      • 您可能已经想通了,但是要回答您关于如何跳过记录的问题,请检查配置“ShouldSkipRecord”,您可以设置在这种情况下调用的回调函数。
      • 似乎将 try/catch 放在这样的 while 循环中会大大减慢整个过程。我在循环使用约 500k 行的 .csv 时注意到了这一点
      【解决方案3】:

      CsvHelperCsvReader 中有公共的 'Context' 字段,并且有显示问题所需的所有内容:

      try
      {
          var records = csvReader.GetRecords<MyType>().ToList();
      }
      catch (CsvHelperException e)
      {
          Console.WriteLine($"{e.Message} " + (e.InnerException == null ? string.Empty : e.InnerException.Message));
          Console.WriteLine($"Row: {csvReader.Context.Row}; RawLine: {csvReader.Context.RawRecord}");
          if (csvReader.Context.CurrentIndex >= 0 &&
              csvReader.Context.CurrentIndex < csvReader.Context.HeaderRecord.Length)
          {
              Console.WriteLine($"Column: {csvReader.Context.CurrentIndex}; ColumnName: {csvReader.Context.HeaderRecord[csvReader.Context.CurrentIndex]}");
          }
          throw;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-25
        • 2015-08-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多