CsvHelper ConvertUsing not changing output
Asked Answered
M

2

12

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?

Marrilee answered 10/2, 2014 at 13:19 Comment(0)
M
12

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.

Mug answered 10/4, 2014 at 20:26 Comment(3)
So what would someone do to modify output before writing a file?Gearwheel
@GeorgeStocker I added more to the answer.Mug
There is a simple(r) example over here on writing to csv with a custom type-converter: https://mcmap.net/q/339755/-custom-conversions-when-writing-csv-files-using-csvhelperTawnytawnya
P
9

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.

Poucher answered 30/6, 2015 at 12:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.