'Trying to implement a type converter for CsvHelper has no effect
I am trying to globally register a CsvHelper type converter that handles the value NULL
for a decimal?
, but when I do the registration is ignored and the converter is not invoked. Not sure what else to do.
My converter:
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);
}
}
My class and mapping are as follows:
public class Model
{
public decimal? Score{ get; set; }
}
public class ScoreMapping : ClassMap<Model>
{
public ScoreMapping()
{
Map(m => m.Score).Name("sub_score");
}
}
And to set it up
csvReader.Context.RegisterClassMap<ScoreMapping>();
csvReader.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
var records = csvReader.GetRecords<Model>().ToList();
But the library doesn't do it
CsvHelper.TypeConversion.TypeConverterException : The conversion cannot be performed.
Text: 'NULL'
MemberType: System.Nullable`1[[System.Decimal, System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]
TypeConverter: 'CsvHelper.TypeConversion.NullableConverter'
Demo fiddle here.
As a workaround, it seems I can add the TypeConverter on each type, but this is clunky, is there a proper way to register the type converter globally?
Map(m => m.Score).Name("sub_score").TypeConverter<NullDecimalConverter>();
Solution 1:[1]
The issue here was order of execution...
AddConverter
must be called before RegisterClassMap
else the converter will not be registered.
I reckon I should raise this as a bug because relying on order is probably something to avoid, especially in a library where this could easily be overlooked.
// fails because class map is registered first
csv.Context.RegisterClassMap<ScoreMapping>();
csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
// works because TypeConverter is added first
csv.Context.TypeConverterCache.AddConverter<decimal>(new NullDecimalConverter());
csv.Context.RegisterClassMap<ScoreMapping>();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | PandaWood |