Search code examples
c#json.netcsvhelper

json to csv : C#


New to C# and hopefully there is a simple fix for this. Using Newtonsoft and CsvHelper packages to convert a json to csv file. I dont have any control over input json. so, input json could have 'attr4' 'attr5' and so on (or without 'attr1' .. ) . in the code below, section using foreach is working as expected.

I am hoping to avoid foreach in the second section (mycsv2.csv writing), but thats not working.

I am new to all these and I am hoping this is simple mistake.

    public static void jsonToCsv()
    {
        string json = @"{
                'attr1': 'val1',
                'attr2': 'val2',
                'attr3': 'val3'                      
            }";

        //working
        var records = new List<object> {};
        JObject jObj = JObject.Parse(json);
        dynamic obj = new ExpandoObject();

        foreach (JProperty property in jObj.Properties())
        {
            AddProperty(obj, property.Name, property.Value.ToString());
        }
        records.Add(obj);                    

        using (var writer = new StreamWriter("C:\\csv\\mycsv1.csv"))
        using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csv.WriteRecords(records);
        }

        //NOT working

        var recordsD = new List<object> {};
        JObject jObjD = JObject.Parse(json);
        dynamic objD = new ExpandoObject();
        objD = jObjD.ToObject<object>();            
        records.Add(objD);

        using (var writer = new StreamWriter("C:\\csv\\mycsv2.csv"))
        using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
        {
            csv.WriteRecords(recordsD);
        }

    }

    public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
    {
        // ExpandoObject supports IDictionary so we can extend it like this
        var expandoDict = expando as IDictionary<string, object>;
        if (expandoDict.ContainsKey(propertyName))
            expandoDict[propertyName] = propertyValue;
        else
            expandoDict.Add(propertyName, propertyValue);
    }

Solution

  • You could cast to ExpandoObject not Object in the second query, like the following code:

    var recordsD = new List<object> { };
    JObject jObjD = JObject.Parse(json);
    dynamic objD = new ExpandoObject();
    
    objD = jObjD.ToObject<ExpandoObject>();
    recordsD.Add(objD);
    

    This give the same result as first request.

    I hope this help you fix the issue.