Closed Stumpii closed 6 years ago
The BooleanConverter
doesn't do anything special for writing, so you'll have to implement your own that overrides the ConvertToString
method and outputs what you want. You can inherit from BooleanConverter
still to get the reading part for free.
Based on your code, it looks like you may have tried this already. You should be able to globally set a type converter for a type.
void Main()
{
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
using (var reader = new StreamReader(stream))
using (var csv = new CsvWriter(writer))
{
var records = new List<Test>
{
new Test { Id = 1, Name = "one", IsTrue = true },
new Test { Id = 2, Name = "two", IsTrue = false },
};
csv.Configuration.TypeConverterCache.AddConverter<bool>(new YesNoConverter());
csv.WriteRecords(records);
writer.Flush();
stream.Position = 0;
reader.ReadToEnd().Dump();
}
}
public class Test
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsTrue { get; set; }
}
public class YesNoConverter : BooleanConverter
{
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
//var boolValue = value as bool?;
if (value is bool boolValue)
{
return boolValue ? "Yes" : "No";
}
return base.ConvertToString(value, row, memberMapData);
}
}
AddConverter
will replace an existing converter.
Thanks. I had ended up with basically the same thing, then included ConvertFromString so that conversions both way are together:
internal class BooleanYesNoConverter : BooleanConverter
{
public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
{
switch (text.ToLower())
{
case "yes":
return true;
case "no":
return false;
}
return base.ConvertFromString(text, row, memberMapData);
}
public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
{
if (value is bool boolValue)
{
return boolValue ? "Yes" : "No";
}
return base.ConvertToString(value, row, memberMapData);
}
}
I also switched to using attributes to set which fields use the converter, instead of a global converter. I might try your way.
By the way, thanks for the great library.
Awesome and you're welcome!
I have a CSV that uses Yes/No instead of True/False for booleans. I have configured the reader as such, which seemed to most efficient way and work great:
Trouble comes when I write. The TypeConverterOptions are only for reading, not writing. I have tried a global TypeConverter as below:
However this does not work, my assumption being that I am writing with 'WireRecords' which does not appear to call the type converter. If I apply the typeconverter in mapping:
Then it does work. However I have 17 maps, each with multiple bool values, so I really want to specify at the global level, not the mapping level.
Is my assumption correct and/or is there a work around?
Thanks, Steve