29

I have some class

public class Import
{
    public DateTime Date { get; set; }
    public string Category { get; set; }
}

In csv file header names can be in lowercase. How I can ignore case while reading file?

    var reader = new StreamReader(@"///");
    var csv = new CsvReader(reader);
           
    var records = csv.GetRecords<Import>().ToList();
Steve Friedl
  • 3,929
  • 1
  • 23
  • 30
Starter
  • 329
  • 1
  • 3
  • 9

3 Answers3

34

If you are using the http://joshclose.github.io/CsvHelper/ you can provide some configuration when constructing the CsvReader or configuring it after construction.

    using (var stringReader = new StringReader(yourString))
    using (var csvReader = new CsvReader(stringReader))
    {
        // Ignore header case.
        csvReader.Configuration.PrepareHeaderForMatch =  (string header, int index) => header.ToLower();
        return csvReader.GetRecords<Import>().ToList();
    }

There is more documentation in the PrepareHeaderForMatch section at https://joshclose.github.io/CsvHelper/api/CsvHelper.Configuration/Configuration/

For more granularity there are also class mapping instructions for which can be found under here: https://joshclose.github.io/CsvHelper/examples/configuration

Hope that helps.

Jesse Hufstetler
  • 583
  • 7
  • 13
ozzy
  • 999
  • 12
  • 12
  • 4
    Going the `PrepareForMatch ToLower()` route - wouldn't that require the C# class you're binding to to have its properties all lower case? I.e. still requiring that the casing of the input and your model match? Otherwise again... they'll have different cases. Requiring matching case is far from "case insensitive" – Don Cheadle Jul 03 '18 at 14:47
  • 2
    Random old CsvHelper code shows `csvReader.Configuration.IsHeaderCaseSensitive = true;` but this Configuration property doesn't look to be a part of the library now? Looks like the silver bullet was removed. – Don Cheadle Jul 03 '18 at 14:56
  • 3
    @mmcrae I thought the same thing at first but according to the documentation, "The header field and the member name are both ran through this function." – KevinVictor Oct 04 '18 at 17:39
  • 7
    @DonCheadle the ToLower() is run over the headers from the file as well as the properties of the class, so in effect a case-insensitive comparison is done. – kristianp Nov 21 '19 at 21:32
  • 2
    Hi all, this solution is no longer supported as the configuration API has changed. For me, @Ambrose Leung's change worked https://stackoverflow.com/a/67167414/9301751 – Reece Russell Nov 21 '22 at 14:27
23

In the current version of CsvHelper, you have to configure it like this:

var csvConfig = new CsvConfiguration(CultureInfo.InvariantCulture)
{
    PrepareHeaderForMatch
    = args => args.Header.ToLower()
};
using (var reader = new StreamReader(inputFile))
using (var csv = new CsvReader(reader, csvConfig))
{
    ...
}
Ambrose Leung
  • 3,704
  • 2
  • 25
  • 36
0

A blog post from Mak (2022-09-26) has three different ways to configure CsvHelper.

When your CSV header names don’t match your property names exactly, CsvHelper will throw an exception. For example, if your header name is “title” and your property name is “Title”, it’ll throw an exception like: HeaderValidationException: Header with name ‘Title'[0] was not found.

If you don’t want to (or can’t) change the names to match, then you can configure CsvHelper to map headers to properties with different names. You have three options:

  • Use the [Name] attribute on properties that need it.
  • Use CsvConfiguration.PrepareHeaderForMatch when there’s a pattern to the naming differences (such as a casing difference).
  • Use a ClassMap to explicitly declare how all properties should be mapped.

C# – Configuring CsvHelper when the header names are different from the properties

ofthelit
  • 1,341
  • 14
  • 33