読み込んだ CSV のある Header の値を C# のクラスプロパティにマッピングさせて Deserialize したい場合がある。 そんなときの方法をメモ。
例として CSV で本の「タイトル」「著者」をまとめていたとして、これを C# の Book class に Deserialize する。
public class Book { public string Title { get; init; } public string Author { get; init; } }
環境は以下
- net6.0
- CsvHelper 30.0.1
Deserialize するクラスに Attribute を付ける
これが最もシンプルな方法かな。
using CsvHelper.Configuration.Attributes; public class Book { [Name("タイトル")] public string Title { get; init; } [Name("著者")] public string Author { get; init; } }
このクラスを CsvReader の GetRecords の型パラメータに指定すると CSV ファイルの「タイトル」の値を「Title」に、「著者」の値を「Author」にマッピングして Deserialize してくれる。
ClassMap を使う
Attribute を付けたくないときは ClassMap を使う。
using CsvHelper.Configuration; public class BookClassMapper: ClassMap<Book> { public BookClassMapper() { Map(b => b.Title).Name("タイトル"); Map(b => b.Author ).Name("著者"); } }
CsvReader.Context の RegisterClassMap の型パラメータにこのクラスを指定すると Attribute を指定した場合と同じ Deserialize 結果になる。
using var csvReader = new CsvReader(sr, new CsvConfiguration(CultureInfo.InvariantCulture) { HasHeaderRecord = true }); csvReader.Context.RegisterClassMap<BookClassMapper>();
CSV にヘッダーがないとどうなるの
例えば読み込む CSV のヘッダーに「タイトル」が含まれていないとすると Parse Exception
が発生する。これの例外をバリデーションに使うなり出来る。