CSV to JSON with dynamic objects name fields

195 Views Asked by At

I have a number of CSV files which I desire to translate to JSON files using Cinchoo. I'll need to rename the fields (and convert them into the desired data type). I'm having trouble renaming the fields.

Dummy input file:

VE NUMMER;VE NAAM;EFFECTDATUM;EINDDATUM
123;abc;20221001;
124;def;20221001;
125;ter;20221001;
126;ddf;20221001;

Expected Output:

[
{
    "Id": 123,
    "Name": "abc",
    "Date": "20221001"
},
{
    "Id": 124,
    "Name": "def",
    "Date": "20221001"
}, ...
]

I've tried

  • Using the BeforeRecordWrite event, but this is throwing errors when renaming the property
  • Using a custom ContractResolver but this seems to be ignored
  • Using a custom JsonConverter but this seems to be ignored
using ChoETL;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Reflection;

internal class Program
{
    private static void Main(string[] args)
    {
        QuickConversion();

    }

    private static void QuickConversion()
    {
        using var r = new ChoCSVReader("./Data./DummyFile.CSV")
               .WithFirstLineHeader()
               .WithDelimiter(";")
               .WithEOLDelimiter("\r\n")
               .MayHaveQuotedFields();

        using var w = new ChoJSONWriter(Console.Out)
           //.JsonSerializationSettings(settings =>
           //{
           //    settings.NullValueHandling = NullValueHandling.Ignore;
           //    settings.Formatting = Formatting.Indented;
           //    settings.MaxDepth = 2;
           //    settings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
           //    settings.ContractResolver = new CustomContractResolver("VE NUMMER", "ID");
           //})
           .WithJSONConverter(new CustomConverter())
        .UseJsonSerialization();

        w.Write(r);
    }
}

public class CustomConverter : JsonConverter
{
    public override bool CanConvert(Type objectType) => true;
    public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) => throw new NotImplementedException();
    public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
    {
        serializer.ContractResolver = new CustomContractResolver("VE NUMMER", "ID");
    }
}
public class CustomContractResolver : DefaultContractResolver
{
    public string SourcePropertyName { get; set; }
    public string TargetPropertyName { get; set; }
    public CustomContractResolver(string sourcePropertyName, string targetPropertyName)
    {
        SourcePropertyName = sourcePropertyName;
        TargetPropertyName = targetPropertyName;
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        var property = base.CreateProperty(member, memberSerialization);
        Console.WriteLine(property.PropertyName);

        if (property.PropertyName == SourcePropertyName)
        {
            property.PropertyName = TargetPropertyName;
        }
        return property;
    }
}
1

There are 1 best solutions below

3
PinBack On BEST ANSWER

Maybe it is possible to specify the fields already during import:

using var r = new ChoCSVReader("./Data./DummyFile.CSV")
        .WithFields("Id", "Name", "Date")
        .WithFirstLineHeader(true)
        .WithDelimiter(";")
        .WithEOLDelimiter("\r\n")
        .MayHaveQuotedFields();

Then you do not need a CustomConverter