Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"N/A" as null value of int field

Tags:

c#

csvhelper

I have to work with (i.e. I have no control over) csv files where "N/A" is a possible value for fields that "should" be ints, and I have been trying to figure out how to "roll my own" TypeConversion class to handle this, but have not been able to find examples. Josh's examples page is conspicuously lacking in this particular area and the closest stackoverflow question I've been able to find is this one from 2013.

Then I found references to the NullValuesAttribute, which seems like exactly what I needed but then couldn't figure out how to use it. VisualStudio's Intellisense was no help either. :)

Ideally I'd like the "N/A"s to convert to 0 (zero). Can someone help?

Before people tell me "Well, it's obvious..." I should say that this is my first (literally, aside from tutorials) C# program and there is also a time factor - or I'd quite happily explore on my own.

[Update: tried top adapt solution at CsvHelper Parsing boolean from String ]

So, taking solution for the above question as a starting point, I did this:

static void Main()
{
    var rows = new List<Job>();

    using (var reader = new StreamReader("mydatafile.csv")
    using (var csv = new CsvReader(reader))
    {
         csv.Configuration.RegisterClassMap<JobMap>();
         while (csv.Read())
         {
              var record = new Job
              {
                   JobId = csv.GetField<int>("Job ID"),
                   ItemCount = csv.GetField<int>("Item Count")
              };
              rows.Add(record);
         }
    }
}

public class Job
{
    public int JobId { get; set; }
    public int ItemCount { get; set; }
}

public sealed class JobMap : ClassMap<Job>
{
    Map(m => m.JobId);
    Map(m => m.ItemCount).TypeConverterOption.NullValues("N/A");
}

My thinking was that specifying the NullValues would get the TypeConverter to convert "N/A" into a null (since there doesn't appear to be an Int32 equivalent of the "BooleanValues" method.

Unfortunately, this still threw an exception:

CsvHelper.TypeConversion.TypeConverterException: 'The conversion cannot be performed.
Text: 'N/A'
MemberType: 
TypeConverter: 'CsvHelper.TypeConversion.Int32Converter''

So, looks like I'm going to have to extend Int32Converter. Yes?

like image 596
Colin Wu Avatar asked Mar 21 '19 01:03

Colin Wu


1 Answers

You can define a custom type converter like this:

using CsvHelper;
using CsvHelper.TypeConversion;
using CsvHelper.Configuration;

public class CustomInt32Converter: Int32Converter {
    public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
    {
        if (text == "N/A") return 0;
        return base.ConvertFromString(text, row, memberMapData);
    }
}

Then you can register your converter with this line:

csv.Configuration.TypeConverterCache.AddConverter<int>(new CustomInt32Converter());
like image 154
Meta-Knight Avatar answered Nov 11 '22 05:11

Meta-Knight