CSVHelper mandatory fields

老子叫甜甜 提交于 2019-12-22 06:59:10

问题


When parsing a csv file, how do i define that a specific field is mandatory. Essentially, I want to make sure that a given field is never empty, and if it is then I would like an exception thrown. Here is the mapping class:

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
    }
}

and the usage:

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

Currently I am just checking the results in the data list as follows:

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

I was unable to find a built-in feature in the CSVHelper documentation. Am I missing something?


回答1:


I'd probably do this using the ConvertUsing extension:

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");
        });
    }
}



回答2:


Here is a solution that extends the 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);
        });
    }
}

Usage:

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



回答3:


As suggested by the creator of CsvHelper here:

For the time being, I think you'll have to have WillThrowOnMissingField = false and run a loop and check your specific required fields. You can probably just check the header after the first read.

His sample code:

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>() );
}



回答4:


The developer has now added a Validate method: https://joshclose.github.io/CsvHelper/examples/configuration/class-maps/validation

Using this to validate against a non-null or empty string:

Map(m => m.Id).Validate(field => !string.IsNullOrEmpty(field));

https://github.com/JoshClose/CsvHelper/issues/556



来源:https://stackoverflow.com/questions/26712912/csvhelper-mandatory-fields

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!