简体   繁体   中英

Convert CSV to JSON, How to address columns containing comma(,) using c#

I tried to convert CSV data to JSON. It quiet worked fine but few columns have comma, while converting to json, comma contained data is getting split. This is the code I tried,

var path = @"C:xyz\\abc.csv";
            var csv = new List<string[]>();
            var lines = File.ReadAllLines(path);

            foreach (string line in lines)
                csv.Add(line.Split(','));

            var properties = lines[0].Split(',');

            var listObjResult = new List<Dictionary<string, string>>();

            for (int i = 1; i < lines.Length; i++)
            {
                var objResult = new Dictionary<string, string>();
                for (int j = 0; j < properties.Length; j++)
                    objResult.Add(properties[j], csv[i][j]);

                listObjResult.Add(objResult);
            }
            var json = JsonConvert.SerializeObject(listObjResult, Formatting.Indented);
            List<ABCModel> desrilize = JsonConvert.DeserializeObject<List<ABCModel>>(json);
            return desrilize;

CSV data

employee,emp city,state,emp address
"abc","efg","lkj","building name"
"wer","sdf","qwe","afj Building, near cross"

In above third line contains comma, which should not get split while converting to json. Where as using above code, its getting split. Kindly help.

Also there is a space in "emp city", how to define jsonProperty for the same while creating model.

Expected json

[
  {
    "employee": "abc",
    "emp city": "efg",
    "state": "lkj",
    "emp address": "building name"
  },
  {
    "employee": "wer",
    "emp city": "sdf",
    "state": "qwe",
    "emp address": "afj Building, near cross"
  }
]

You can try with csvHelper or csv converter. using csv:

var options = new CsvOptions // Defaults
            {
                RowsToSkip = 0, // Allows skipping of initial rows without csv data
                SkipRow = (row, idx) => string.IsNullOrEmpty(row) || row[0] == '#',
                Separator = '\0', // Autodetects based on first row
                TrimData = false, // Can be used to trim each cell
                Comparer = null, // Can be used for case-insensitive comparison for names
                HeaderMode = HeaderMode.HeaderPresent, // Assumes first row is a header row
                ValidateColumnCount = true, // Checks each row immediately for column count
                ReturnEmptyForMissingColumn = false, // Allows for accessing invalid column names
                Aliases = null, // A collection of alternative column names
                AllowNewLineInEnclosedFieldValues = false, // Respects new line (either \r\n or \n) characters inside field values enclosed in double quotes.
                AllowBackSlashToEscapeQuote = false, // Allows the sequence "\"" to be a valid quoted value (in addition to the standard """")
                AllowSingleQuoteToEncloseFieldValues = false, // Allows the single-quote character to be used to enclose field values
                NewLine = Environment.NewLine // The new line string to use when multiline field values are read (Requires "AllowNewLineInEnclosedFieldValues" to be set to "true" for this to have any effect.)
            };

            var csv = File.ReadAllText(fileName or filePath);
            foreach (var line in CsvReader.ReadFromText(csv, options))
            {
                yourModel.Add(new yourModel()
                {
                    StoneCode = line["Field1"],
                    StoneTypeName = line["Field2"],
                });
            }

To read your desired CSV input by using CsvHelper, this example should help you:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using CsvHelper;
using CsvHelper.Configuration;

public class Program
{
    public static void Main()
    {
        var csvContent = @"employee,emp city,state,emp address
""abc"",""efg"",""lkj"",""building name""
""wer"",""sdf"",""qwe"",""afj Building, near cross""";

        List<Employee> employees;
        using (var reader = new StringReader(csvContent))
        using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
        {
            csv.Context.RegisterClassMap<EmployeeMap>();
            var records = csv.GetRecords<Employee>();
            employees = records.ToList();
        }

        foreach (var employee in employees)
        {
            Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(employee));
        }
    }
}

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Map(e => e.Name).Name("employee");
        Map(e => e.City).Name("emp city");
        Map(e => e.State).Name("state");
        Map(e => e.Address).Name("emp address");
    }
}

public class Employee
{
    public string Name { get; set; }

    public string City { get; set; }

    public string State { get; set; }

    public string Address { get; set; }
}

Here is another one to the list, Cinchoo ETL - an open source library does the job of converting CSV to JSON quickly as below

string csv = @"employee,emp city,state,emp address
""abc"",""efg"",""lkj"",""building name""
""wer"",""sdf"",""qwe"",""afj Building, near cross""";

using (var r = ChoCSVReader.LoadText(csv)
       .WithFirstLineHeader()
       .MayHaveQuotedFields()
      )
{
    using (var w = new ChoJSONWriter(Console.Out))
    {
        w.Write(r);
    }
}

Output:

[
  {
    "employee": "abc",
    "emp city": "efg",
    "state": "lkj",
    "emp address": "building name"
  },
  {
    "employee": "wer",
    "emp city": "sdf",
    "state": "qwe",
    "emp address": "afj Building, near cross"
  }
]

Sample fiddle: https://dotnetfiddle.net/Dk4vtO

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM