Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trouble with CSV-Helper not converting bool values

I'm starting to use CSV Helper - an excellent little helper for your daily work - great stuff!

One item I'm struggling with right now are class maps - I have a little class

public class SimpleClass
{
    public int ID { get; set; }
    public string Name { get; set; }
    public decimal Percentage { get; set; }
    public bool IsValid { get; set; }
}

and for exporting to CSV, I would like to replace the IsValid values true with yes, False with no; for that purpose, I've created a class map:

public class SimpleClassMap : CsvClassMap<SimpleClass>
{
    public override void CreateMap()
    {
        Map(x => x.ID).Index(0);
        Map(x => x.Name).Index(1);
        Map(x => x.Percentage).Index(2);
        Map(x => x.IsValid).Index(3)
                           .TypeConverterOption(true, "yes")
                           .TypeConverterOption(false, "no");
    }
}

and now when exporting my data, I'm using that class map:

CsvConfiguration config = new CsvConfiguration { Delimiter = ";", HasHeaderRecord = false, Quote = '"' };
config.RegisterClassMap<SimpleClassMap>();

using (MemoryStream stm = new MemoryStream())
using (var streamWriter = new StreamWriter(stm))
using (var csvWriter = new CsvWriter(streamWriter, config))
{
    csvWriter.WriteRecords(list);
    streamWriter.Flush();
}

Unfortunately, when I inspect what has been written, I see that I still get True or False - not the yes or no as I had hoped.....

What am I missing here? I'm using CSV-Helper v2.5, installed from NuGet, and .NET 4.0 / Visual Studio 2010.

like image 339
marc_s Avatar asked Mar 31 '14 13:03

marc_s


1 Answers

The boolean values overload for TypeConverterOption is used only when reading. It allows you to specify multiple values that can be used for true/false when reading. So you could do 1, "true", "TRUE", "True", "yes", etc.

Currently the only way to do it when writing is to create a custom type converter.

public class MyBooleanConverter : DefaultTypeConverter
{
    public override string ConvertToString( TypeConverterOptions options, object value )
    {
        if( value == null )
        {
            return string.Empty;
        }

        var boolValue = (bool)value;

        return boolValue ? "yes" : "no";
    }
}

You can then apply it to all booleans globally.

CsvHelper.TypeConversion.TypeConverterFactory.AddConverter<bool>( new MyBooleanConverter() );

Or apply it to a single property via the mapping.

Map( m => m.MyBoolProperty ).TypeConverter<MyBooleanConverter>();
like image 74
Josh Close Avatar answered Oct 18 '22 10:10

Josh Close