CSVHelper 必填字段

7

在解析csv文件时,如何定义特定字段是必填的。本质上,我想确保给定的字段永远不为空,如果为空,则希望抛出异常。以下是映射类:

public sealed class DataMapper : CsvClassMap<DataType>
{
    public DataMapper()
    {
        Map(m => m.Field1).Name("FirstField");
        Map(m => m.Field2).Name("SecondField");
        Map(m => m.Field3).Name("ThirdField"); // this field should be mandatory
    }
}

使用说明:

List<DataType> data;
using (var sr = new StreamReader(localFilePath))
{
    var reader = new CsvReader(sr);
    reader.Configuration.RegisterClassMap<DataMapper>();
    data = reader.GetRecords<DataType>().ToList();
}

目前,我只是按照以下方式检查数据列表中的结果:

var numberOfInvalidRecords = data.Count(data => string.IsNullOrEmpty(data.Field3));
if (nullAccountHolderRecords > 0)
{
    //handle
}

我在CSVHelper的文档中找不到内置功能。我有什么遗漏吗?

4个回答

7

以下是扩展API的解决方案:

public static class CsvHelperExtensions
{
    public static CsvPropertyMap Required<T>(this CsvPropertyMap map, string columnName)
    {
        return map.Name(columnName).ConvertUsing(row =>
        {
            if (string.IsNullOrEmpty(row.GetField(columnName)))
                throw new CsvParserException($"{columnName} is required, but missing from row {row.Row}");
            return row.GetField<T>(columnName);
        });
    }
}

使用方法:

public CsvPersonMap()
{
    Map(m => m.FirstName).Required<string>("First");
    Map(m => m.LastName).Name("Last");
    Map(m => m.MiddleName).Required<string>("Middle");
}

6

我可能会使用ConvertUsing扩展来实现:

public sealed class DataMapper : CsvClassMap<DataType>
{
    public DataMapper()
    {
        Map(m => m.Field1).Name("FirstField");
        Map(m => m.Field2).Name("SecondField");
        Map(m => m.Field3).ConvertUsing(row =>
        {
            if(string.IsNullOrEmpty(row.GetField<string>("ThirdField")))
                throw new Exception("Oops, ThirdField is empty!");
            return row.GetField<string>("ThirdField");
        });
    }
}

新版本的库已经移除了“Get”方法,并用“GetField”方法进行了替换。 - Hakan Fıstık
@HakamFostok 谢谢,你应该在那时候修复它 :) - DavidG

3

2

正如CsvHelper的创建者建议的那样

目前而言,我认为您必须将WillThrowOnMissingField设置为false,然后运行一个循环并检查您特定所需的字段。您可以在第一次读取后仅检查标题。

他的示例代码:

csv.WillThrowOnMissingField = false;
var list = new List<MyObject>();
var headerChecked = false;
while( csv.Read() )
{
    if( !headerChecked )
    {
        // check for specific headers
        if( !csv.FieldHeaders.Exists( "MyHeaderName" ) )
        {
            throw new Exception( "message" );
        }
        headerChecked = true;
    }

    list.Add( csv.GetRecord<MyObject>() );
}

1
这只有在检查源文件是否具有该列时才有用。OP正在要求确保该值不为空。 - DavidG
FieldHeaders不再受支持。 - rjose

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接