Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CsvHelper ConvertUsing not changing output

I'm trying to use the ConvertUsing method of the CsvHelper library (v 2.4.0).

I've read the documentation about ConvertUsing but can't get it to work.

I'm using a simple class:

public class Test
{
    public long Id { get; set; }
    public string Title { get; set; }
}

With this ClassMap:

public class TestClassMap : CsvClassMap<Test>
{
    public override void CreateMap()
    {
        Map(m => m.Id).Name("id").ConvertUsing(row => 11111);
        Map(m => m.Title).Name("title").ConvertUsing(row => row.GetField("title") + " 123");
    }
}

My code which uses these creates an instance of the class and then writes it to CSV:

var test = new Test() { Id = 99, Title = "Test title" };

using (var streamWriter = new StreamWriter("test.csv"))
{
    var csv = new CsvWriter(streamWriter);
    csv.Configuration.RegisterClassMap<TestClassMap>();
    csv.WriteRecord(test);
}

However the output file test.csv is always the following format:

id,title
99,Test title

The output I'm looking for is:

id,title
11111,Test title 123

And the ConvertUsing is being ignored. I've tried only converting the Id, and only the Title, but this doesn't work either.

Any ideas where I'm going wrong?

like image 752
finoutlook Avatar asked Feb 10 '14 13:02

finoutlook


Video Answer


2 Answers

I had a similar need and this is what I made in order to modify the content before saving it into a csv file.

I have a custom class called StringNormalizer that implements CsvHelper.TypeConversion.ITypeConverter interface.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CsvHelper.TypeConversion;

namespace MyNamespaceInHere {    
    public class StringNormalizer : ITypeConverter {
        public bool CanConvertFrom(Type type) {
            if (type == typeof(string)) return true;
            return false;
        }
        public bool CanConvertTo(Type type) {
            if (type == typeof(string)) return true;
            return false;
        }
        public object ConvertFromString(TypeConverterOptions options, string text) { return normalize(text); }
        public string ConvertToString(TypeConverterOptions options, object value) {
            if (value == null) return string.Empty;
            if (value.GetType() == typeof(string)) {
                string str = (string)value;
                return normalize(str);
            }
            return string.Empty;
        }
        public string normalize(string field) {
            // Do stuff in here and return normalized string
            return field + " just a sample";
        }
    }
}

Then in my main program where I have defined mappings I use it like this

public sealed class ConMap : CsvClassMap<Contact> {        
        public override void CreateMap() {
            Map(m => m.FirstName).Name("FirstName").TypeConverter<StringNormalizer>();
        }
    }

And thus all that is saved to csv are "run through" my string normalizer.

like image 161
kivikall Avatar answered Sep 30 '22 14:09

kivikall


Currently ConvertUsing is only used when reading.

You can use a custom type converter if you want to customize the output. You also have some limited abilities through the type converter options.

like image 45
Josh Close Avatar answered Sep 30 '22 12:09

Josh Close