CsvHelper,当header无效时列出预期的header

CsvHelper, list the expected header when headers are invalid

使用 CsvHelper 读取 CSv 文件,您可以在 ClassMap:

中指定预期的 Header
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();
    }

}

映射的每个 属性 都是必需的和预期的,可选的用于区分可能存在或可能不存在的 属性。

Header 由 Action<bool, string[], int, ReadingContext> HeaderValidated 验证,具有相应的参数:isValid、headerNames、headerNameIndex、context。 当不缺少 header 时,isValid 为 false。 headerNames 和 'headerNameIndex' 将分别包含 header 的预期名称或索引。 我可以用它来知道缺少 header。

如何访问预期列表 header? ReadingContext context 的许多属性将包含当前 header.

的列表

我可以使用验证循环将所有 headerNames 和 'headerNameIndex' 添加到列表中。

var errorSb = new StringBuilder();
[...]
csvReader.Configuration.HeaderValidated =
    (isValid, headerNames, headerNameIndex, context) =>
    {
        allHeaderNames.Add(headerNames);
        if (!isRowValid)
        {
            isHeaderInvalid= true;
        }
    };

我真正想要的是readFooMapper映射配置。
告诉用户:"Look I expect This list of columns: ##, ##, ##. With those optional columns: X,Y,Z. \n Missing column = A,B,C."

而且这无需维护另一个列表 Headers 和可选。

我认为这与您要查找的内容很接近。它不会检查您的 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();