Using CsvHelper can I translate white space to a nullable?
In the end I went with creating my own type converter that will treat whitespace the same as a null.
public class WhiteSpaceToNullableTypeConverter<T> : TypeConverter where T : struct
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof (string);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof (T?);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
object value)
{
T? result = null;
var stringValue = (string) value;
if (!string.IsNullOrWhiteSpace(stringValue))
{
var converter = TypeDescriptor.GetConverter(typeof(T));
result = (T)converter.ConvertFrom(stringValue.Trim());
}
return result;
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture,
object value, Type destinationType)
{
var result = (T?) value;
return result.ToString();
}
}
Apply it to your model like this
public class Test
{
[CsvField(Name = "Text")]
public string Text { get; set; }
[CsvField(Name = "SomeDouble")]
[TypeConverter( typeof( WhiteSpaceToNullableTypeConverter<Double> ) )]
public double? SomeDouble{ get; set; }
[CsvField(Name = "MoreText")]
public string MoreText{ get; set; }
}
A simple way is to use ConvertUsing()
in your ClassMap
:
Map(x => x.SomeDouble)
.ConvertUsing(row =>
string.IsNullOrWhiteSpace(row.GetField("SomeDouble")) ?
(double?) null :
Convert.ToDouble(row.GetField("SomeDouble")));
I like to make little helper functions and call them
Map(x => x.SomeDouble)
.ConvertUsing(row => GetOddballDouble(row.GetField("SomeDouble")));