using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Globalization;
using System.Collections.ObjectModel;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using CsvHelper.Expressions;
using CsvHelper.TypeConversion;
public class NullDecimalConverter : DecimalConverter
public override object ConvertFromString(string text, IReaderRow row, MemberMapData mapData)
if (text == "NULL") return null;
return base.ConvertFromString(text, row, mapData);
public decimal? Score{ get; set; }
public class ScoreMapping : ClassMap<Model>
Map(m => m.Score).Name("sub_score");
public static void Test()
var csvString = "sub_score\n1.1\n2.2\nNULL";
var config = new CsvConfiguration(CultureInfo.InvariantCulture);
Console.WriteLine(csvString);
using (var reader = new StringReader(csvString))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
csv.Context.RegisterClassMap<ScoreMapping>();
csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
var records = csv.GetRecords<Model>().ToList();
Assert.IsTrue(new decimal?[] { 1.1M, 2.2M, null }.SequenceEqual(records.Select(m => m.Score)));
public static void Main()
Console.WriteLine("Environment version: {0} ({1})", System.Runtime.InteropServices.RuntimeInformation.FrameworkDescription , Environment.Version);
Console.WriteLine("OS Version: {0}, NewLine: {1}", System.Environment.OSVersion, JsonConvert.SerializeObject(Environment.NewLine));
Console.WriteLine("{0} version: {1}", typeof(CsvReader).Assembly.GetName().Name, typeof(CsvReader).Assembly.FullName);
Console.WriteLine("Failed with unhandled exception: ");
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
return base.ConvertToString(value, row, memberMapData);