Search code examples
c#booleancsvreader

Reading CsvReader field text field into Boolean field?


I am new to using CsvReader and it is going well.

My object currently has these fields:

public class CLMExplorerStudent
{
    [Name("Student ID")]
    public int Id { get; set; }

    [Name("Last Name")]
    public string LastName { get; set; }

    [Name("First Name")]
    public string FirstName { get; set; }

    [Name("Gender")]
    public string Gender { get; set; }

    [Name("Active")]
    public string Active { get; set; }

    [Name("Role")]
    public string Role { get; set; }

    [Name("Use For")]
    public string UseFor { get; set; }

    [Name("Use Where")]
    public string UseWhere { get; set; }

    [Name("Email Address")]
    public string EmailAddress { get; set; }

    [Name("Phone #")]
    public string PhoneNumber { get; set; }

    [Name("Remarks")]
    public string Remarks { get; set; }
}

The Active field has a value in the CSV file of Y or N. Is it possible to map this so that the property in my class can be a bool property?

I am using the standard method for reading the CSV file:

using (var reader = new StreamReader(strPath))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
    var records = csv.GetRecords<CLMExplorerStudent>();
}

I obviously know that I can simply test the value against Y or N instead but I would prefer to read into a bool property.

I only need to read in from the CSV file and not write out to it.


Solution

  • Implement a custom type converter and register it using the [TypeConverter] attribute:

    using CsvHelper.Configuration;
    using CsvHelper.Configuration.Attributes;
    using CsvHelper.TypeConversion;
    
    class YesNoConverter : DefaultTypeConverter
    {
        public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
            => "YES".StartsWith(text, StringComparison.OrdinalIgnoreCase);
        
    
        public override string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
            => value is bool b && b ? "Y" : "N";
    }
    
    public class CLMExplorerStudent
    {
        // ...
    
        [Name("Active")]
        [TypeConverter(typeof(YesNoConverter))]
        public bool Active { get; set; }
    
        // ...
    }