CsvHelper,当标题无效时列出预期的标题列表。

4

使用CsvHelper读取CSV文件时,您可以在ClassMap中指定预期的标题:

public sealed class readFooMapper : ClassMap<FooCSV>
{
    public readFooMapper()
    {
        Map(m => m.Id).ConvertUsing(row => ((CsvReader)row).Parser.Context.RawRow);
        Map(x => x.Foo).Name("Foo");
        Map(x => x.Bar).Name("Bar");
        Map(x => x.FooBar).Name("FooBar");
        Map(x => x.MyOptional).Name("MyOptional").Optional();
    }

}

每个映射的属性都是必需的和预期的,可选用于区分可能存在或不存在的属性。
头部通过 HeaderValidated>进行验证,其相应的参数为:isValid,headerNames,headerNameIndex,context。当一个头不缺失时,isValid为false。 'headerNames'和'headerNameIndex'将分别包含头的预期名称或索引。我可以用它来知道哪个头丢失了。
如何访问预期头的列表?ReadingContext context的许多属性将保存当前头列表。
我可以使用验证循环将所有headerNames和'headerNameIndex'添加到列表中。
var errorSb = new StringBuilder();
[...]
csvReader.Configuration.HeaderValidated =
    (isValid, headerNames, headerNameIndex, context) =>
    {
        allHeaderNames.Add(headerNames);
        if (!isRowValid)
        {
            isHeaderInvalid= true;
        }
    };

我真正需要的是readFooMapper映射配置。
告诉用户:"看,我期望这些列:##、##、##。还有这些可选列:X、Y、Z。\n缺少的列为:A、B、C。"
同时无需维护其他标题和可选项列表。
1个回答

4
我认为这接近于您所寻找的内容。它不会检查在您的ConvertUsing方法中是否引用了列。
var map = new readFooMapper();

var required = map.MemberMaps
                  .Where(m => m.Data.Ignore == false 
                           && m.Data.ReadingConvertExpression == null 
                           && m.Data.IsOptional == false)
                  .Select(m => m.Data.Member.Name)
                  .ToList();
var optional = map.MemberMaps
                  .Where(m => m.Data.Ignore == false 
                           && m.Data.ReadingConvertExpression == null 
                           && m.Data.IsOptional == true)
                  .Select(m => m.Data.Member.Name)
                  .ToList();

很好。我在上下文的每个对象中都在寻找,但是MemberMaps正是我所需要的,它不仅仅是接近。 - xdtTransform
请注意,ConvertUsing 可能会引用一个未被映射的列,从而对事情造成影响。 - David Specht

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