如何配置CsvHelper跳过MissingFieldFound行 [英] How to configure CsvHelper to skip MissingFieldFound rows

查看:223
本文介绍了如何配置CsvHelper跳过MissingFieldFound行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

public interface ICsvProductReaderConfigurationFactory
{
    Configuration Build();
}

public class CsvProductReaderConfigurationFactory : ICsvProductReaderConfigurationFactory
{
    private readonly ClassMap<ProductDto> classMap;

    public CsvProductReaderConfigurationFactory(IProductDtoClassMapProvider classMapProvider)
    {
        classMap = classMapProvider.Get();
    }

    public Configuration Build()
    {
        var config = new Configuration
        {
            Delimiter = "\t",
            HasHeaderRecord = true,
            IgnoreQuotes = true,
            MissingFieldFound = (rows, fieldIndex, readingContext) =>
                Log.Warn($"Missing Field Found at line {readingContext.Row}\r\n" +
                         $"Field at index {fieldIndex} does not exist\r\n" +
                         $"Raw record: {readingContext.RawRecord}"),
            BadDataFound = context => 
                Log.Warn($"Bad data found at row {context.Row}\r\n" +
                         $"Raw data: {context.RawRecord}")
        };

        config.RegisterClassMap(classMap);
        return config;
    }
}


public interface ICvsProductReader
{
    IEnumerable<ProductDto> GetAll(string filePath);
}

public class CvsProductReader : ICvsProductReader
{
    private readonly ICsvProductReaderConfigurationFactory csvProductReaderConfigurationFactory;

    public CvsProductReader(ICsvProductReaderConfigurationFactory csvProductReaderConfigurationFactory)
    {
        this.csvProductReaderConfigurationFactory = csvProductReaderConfigurationFactory;
    }

    public IEnumerable<ProductDto> GetAll(string filePath)
    {
        var csvReaderConfiguration = csvProductReaderConfigurationFactory.Build();

        using (var streamReader = new StreamReader(filePath))
        using (var csvReader = new CsvReader(streamReader, csvReaderConfiguration))
        {
            return csvReader.GetRecords<ProductDto>().ToArray();
        }
    }
}

发现缺少的字段时会调用

MissingFieldFound 属性,但不会影响结果.

MissingFieldFound property is called when a missing field is found, but can not affect result.

我想知道是否可以将CsvHelper配置为跳过缺少字段的行.

I was wondering if it's possible to configure CsvHelper to skip rows with missing fields.

推荐答案

您的操作方式没有错,这是一个显示完整示例的mcve

There is nothing wrong the way you did it, here is a mcve showing a complete exemple

var good = new List<Test>();
var bad = new List<string>();

using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
using (var reader = new StreamReader(stream))
using (var csv = new CsvReader(reader))
{
    writer.WriteLine("FirstName,LastName");
    writer.WriteLine("\"Jon\"hn\"\",\"Doe\"");
    writer.WriteLine("\"JaneDoe\"");
    writer.WriteLine("\"Jane\",\"Doe\"");
    writer.Flush();
    stream.Position = 0;

    var isRecordBad = false;

    csv.Configuration.BadDataFound = context =>
    {
        isRecordBad = true;
        bad.Add(context.RawRecord);
    };

    csv.Configuration.MissingFieldFound = (headerNames, index, context) =>
    {
        isRecordBad = true;
        bad.Add(context.RawRecord);
    };

    while (csv.Read())
    {
        var record = csv.GetRecord<Test>();
        if (!isRecordBad)
        {
            good.Add(record);
        }

        isRecordBad = false;
    }
}

good.Dump();
bad.Dump();

这篇关于如何配置CsvHelper跳过MissingFieldFound行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆