2

First of all my apologies because this is going to be a "How to" question rather than a technical question. I have a CSV file as follows-

London,Dubai,4
Dubai,Mumbai,8
Dubai,Dhaka,4

Now my plan is to create a JSON object from that CSV in the following format-

[
  {
    "From": "London",
    "To": "Dubai",
    "Duration": 4

  },
{
    "From": "Dubai",
    "To": "Mumbai",
    "Duration": 8

  },
{
    "From": "Dubai",
    "To": "Dhaka",
    "Duration": 4

  },
]

How do I go about and do that? Currently I can load the CSV using OpenFileDialog but no idea what else I should do to get it done? Use Model Classes? JSON.Net? Please advice me and some code samples would be appreciated!

dre-hh
  • 7,840
  • 2
  • 33
  • 44
envyM6
  • 1,099
  • 3
  • 14
  • 35

3 Answers3

4

You can add csv records to a List<T> and then serialize it with Newtonsoft.Json to get your required JSON object. See the example below:

    class Program
    {
        static void Main(string[] args)
        {
            string[] csv = new[] { "London,Dubai,4", "Dubai,Mumbai,8", "Dubai,Dhaka,4" };
            List<model> list = new List<model>();

            foreach (var item in csv)
            {

                string[] fields = item.Split(',');
                list.Add(new model
                {
                    From = fields[0],
                    To = fields[1],
                    Duration = fields[2]
                });
            }

            var json = JsonConvert.SerializeObject(list);
            Console.WriteLine(json);
            Console.ReadLine();

        }
    }

    public class model
    {
        public string From { get; set; }
        public string To { get; set; }
        public string Duration { get; set; }
    }
Oluwafemi
  • 14,243
  • 11
  • 43
  • 59
  • 2
    Your answer is fine for simple csv files using something like [CSVHelper](https://github.com/joshclose/csvhelper) will save you a lot of time when you use real world data – Filip Cordas Sep 17 '16 at 20:13
0

You can use TextFieldParser from the Microsoft.VisualBasic.FileIO namespace and Microsoft.VisualBasic.dll assembly to parse CSV files. Despite the VisualBasic name the class is perfectly usable in c#.

First, add the following extension method:

public static class TextFieldParserExtensions
{
    public static IEnumerable<string []> ReadAllFields(this TextFieldParser parser)
    {
        if (parser == null)
            throw new ArgumentNullException();
        while (!parser.EndOfData)
            yield return parser.ReadFields();
    }
}

Now you can use LINQ to transform each CSV line into an anonymous or named type for serialization, like so:

        var csv = @"London,Dubai,4
Dubai,Mumbai,8
Dubai,Dhaka,4";

        string json;
        using (var stream = new StringReader(csv))
        using (TextFieldParser parser = new TextFieldParser(stream))
        {
            parser.SetDelimiters(new string[] { "," });
            var query = parser.ReadAllFields()
                .Select(a => new { From = a[0], To = a[1], Duration = int.Parse(a[2]) });
            json = new JavaScriptSerializer().Serialize(query);
        }

Here I am using JavaScriptSerializer but the same code can be used with

            json = JsonConvert.SerializeObject(query, Formatting.Indented);

Be sure to evaluate the query before closing the TextFieldParser.

dbc
  • 104,963
  • 20
  • 228
  • 340
0

I Believe this should work for all different kinds of .csv files

Comments are in the code

public class Program
    {
        public static void Main(string[] args)
        {
            var list = new List<Dictionary<string, string>>();
            Console.WriteLine("Put in the path to your .csv file");
            var response1 = Console.ReadLine();

            Console.WriteLine("Initializing...");
            // Read All of the lines in the .csv file
            var csvFile = File.ReadAllLines(response1);


            // Get The First Row and Make Those You Field Names
            var fieldNamesArray = csvFile.First().Split(',');
            // Get The Amount Of Columns In The .csv
            // Do the -1 so you can use it for the indexer below
            var fieldNamesIndex = fieldNamesArray.Count() - 1;
            // Skip The First Row And Create An IEnumerable Without The Field Names
            var csvValues = csvFile.Skip(1);
            // Iterate Through All Of The Records
            foreach (var item in csvValues)
            {

                var newDiction = new Dictionary<string, string>();
                for (int i = 0; i < fieldNamesIndex;)
                {

                    foreach (var field in item.Split(','))
                    {

                        // Think Of It Like This
                        // Each Record Is Technically A List Of Dictionary<string, string>
                        // Because When You Split(',') you have a string[]
                        // Then you iterate through that string[]
                        // So there is your value but now you need the field name to show up
                        // That is where the Index will come into play demonstrated below
                        // The Index starting at 0 is why I did the -1 on the fieldNamesIndex variable above
                        // Because technically if you count the fields below its actually 6 elements
                        //
                        // 0,1,2,3,4,5 These Are The Field Names
                        // 0,1,2,3,4,5 These Are The Values
                        // 0,1,2,3,4,5
                        //
                        // So what this is doing is int i is starting at 0 for each record
                        // As long as i is less than fieldNamesIndex
                        // Then split the record so you have all of the values
                        // i is used to find the fieldName in the fieldNamesArray
                        // Add that to the Dictionary
                        // Then i is incremented by 1
                        // Add that Dictionary to the list once all of the values have been added to the dictionary
                        //


                        // Add the field name at the specified index and the field value
                        newDiction.Add(fieldNamesArray.ElementAt(i++), field);

                    }
                    list.Add(newDiction);

                }
            }


            Console.WriteLine("Would You Like To Convert To Json Now?");
            Console.WriteLine("[y] or [n]");

            var response = Console.ReadLine();

            if (response == "y")
            {
                Console.WriteLine("Where Do You Want The New File?");
                var response2 = Console.ReadLine();
                // Serialize the list into your Json
                var json = JsonConvert.SerializeObject(list);

                File.Create(response2).Dispose();
                File.AppendAllText(response2, json);

                Console.WriteLine(json);
                Console.ReadLine();
            }
            else
            {
                Console.WriteLine("Ok See You Later");
                Console.ReadLine();
            }

        }

    }
Patrick Mcvay
  • 2,221
  • 1
  • 11
  • 22