35

I was wondering if someone's written a utility to convert a CSV file to Json using C#. From a previous question on stackoverflow, I'm aware of this nice utility - https://github.com/cparker15/csv-to-json and at the moment I plan to refer to it but an existing C# implementation would be very helpful! Thanks!

Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
user1427026
  • 861
  • 2
  • 16
  • 32
  • You could easily transliterate that JS code to C#, you could leave in the `var` keywords too. – tlehman May 30 '12 at 21:08
  • Yep, that's what I'd planned to do but the only article I could find, this one on msdn http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/b6e8a28c-6760-4e86-a1aa-e2ce9ec36380/ uses Office.Interop and I'm a newbie to C# and not really familiar with it. Do I need to use it or should be good trying to translating the js utility? Thanks! – user1427026 May 30 '12 at 21:16
  • 6
    I would avoid using Office.Interop on a CSV file, it would be overkill since CSV is just text. – tlehman May 30 '12 at 21:29

18 Answers18

24

If you can use System.Web.Extensions, something like this could work:

var csv = new List<string[]>(); // or, List<YourClass>
var lines = System.IO.File.ReadAllLines(@"C:\file.txt");
foreach (string line in lines)
    csv.Add(line.Split(',')); // or, populate YourClass          
string json = new 
    System.Web.Script.Serialization.JavaScriptSerializer().Serialize(csv);

You might have more complex parsing requirements for the csv file and you might have a class that encapsulates the data from one line, but the point is that you can serialize to JSON with one line of code once you have a Collection of lines.

mafue
  • 1,858
  • 1
  • 21
  • 27
  • Mostly this result in error if the file is huge. Ex: Error during serialization or deserialization using the JSON JavaScriptSerializer. The length of the string exceeds the value set on the maxJsonLength property – Kurkula Jan 04 '17 at 05:12
23

Cinchoo ETL - an open source library available to do the conversion of CSV to JSON easily with few lines of code

For a sample CSV:

Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC

Sample code,

string csv = @"Id, Name, City
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

StringBuilder sb = new StringBuilder();
using (var p = ChoCSVReader.LoadText(csv)
    .WithFirstLineHeader()
    )
{
    using (var w = new ChoJSONWriter(sb))
        w.Write(p);
}

Console.WriteLine(sb.ToString());

Output JSON:

[
 {
  "Id": "1",
  "Name": "Tom",
  "City": "NY"
 },
 {
  "Id": "2",
  "Name": "Mark",
  "City": "NJ"
 },
 {
  "Id": "3",
  "Name": "Lou",
  "City": "FL"
 },
 {
  "Id": "4",
  "Name": "Smith",
  "City": "PA"
 },
 {
  "Id": "5",
  "Name": "Raj",
  "City": "DC"
 }
]

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

Checkout CodeProject article for some additional help.

UPDATE: If your CSV file has duplicate column names or no names, please use the below steps to produce the JSON file

string csv = @"Id, Name, 
1, Tom, NY
2, Mark, NJ
3, Lou, FL
4, Smith, PA
5, Raj, DC
";

StringBuilder sb = new StringBuilder();
using (var p = ChoCSVReader.LoadText(csv)
    .WithField("Id", position: 1)
    .WithField("Name", position: 2)
    .WithField("City", position: 3)
    .WithFirstLineHeader(true)
    )
{
    using (var w = new ChoJSONWriter(sb))
        w.Write(p);
}

Console.WriteLine(sb.ToString());

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

Disclaimer: I'm the author of this library.

Cinchoo
  • 6,088
  • 2
  • 19
  • 34
  • Thanks for writing this lib @RajN – vibs2006 Mar 23 '18 at 02:25
  • hi, i tried your code, i installed the choetl, but my code found error in "ChoJSONWriter".. "could not be found, are you missing a using directive or assembly". Could you tell me how to use it? what did i miss? – Raspi Surya Aug 08 '18 at 04:53
  • install JSON extension lib (ChoETL.JSON). Corrected the link in SO answer. – Cinchoo Aug 08 '18 at 11:51
  • @RajN I tried out this example and I got it to work perfectly! do you know how to load the csv from a file though instead of a variable? – sbattou Dec 12 '18 at 19:19
  • 1
    Use ChoCSVReader / ChoJSONReader constructors. – Cinchoo Dec 12 '18 at 20:58
  • @RajN using the constructor worked thank you! Any clue how to get the csv as a string? I've tried the following with no luck: `foreach (var e in new ChoCSVReader(csv).WithFirstLineHeader()) { System.Diagnostics.Debug.Write(((object)e).ToString()); }` – sbattou Dec 13 '18 at 17:46
  • 5
    this approach uses dynamic model. `foreach (dynamic e in new ChoCSVReader(csv).WithFirstLineHeader()) { System.Diagnostics.Debug.Write(e.CSVColumnName); }`. For more info, visit CodeProject article / GitHub wiki. – Cinchoo Dec 13 '18 at 18:03
  • this has worked for me `foreach (dynamic e in new ChoCSVReader(csv).WithFirstLineHeader()) { string test = Convert.ToString(e.CSVColumnName);System.Diagnostics.Debug.Write(test);}` One last thing, does your package have any way of renaming the csv column names? @RajN – sbattou Dec 13 '18 at 18:21
  • This doesn't work when one of the headers has the same name, or no name – A X May 25 '19 at 07:22
  • If there are duplicate names or no names in the header. use `WithFirstLineHeader(true)` and use `WithField("Id", position: 1)` to specify the fields by field positions. See my update for sample. – Cinchoo May 26 '19 at 14:01
  • 1
    The library is good it does what it is built for. But when there are some special characters in the key of CSV like i have loerem.lipsm it Converts my key to loerem_lipsm. Is there any solution for this – Yagnesh Khamar Jan 27 '20 at 12:43
  • download 1.1.0.5-beta3 nuget package (or 1.1.0.5 related packages). – Cinchoo Jan 27 '20 at 13:13
  • 1
    This saved me a lot of time doing a conversion from a bunch of csv files to json. Extremely simple to use. Thank you for your library. – blahblah Mar 12 '20 at 11:43
  • @RajN Wonderful library! Is there any way to disable the pretty print when converting from CSV to JSON? I'm trying also to have the number without the quotes, is this possible? – Giox May 19 '20 at 23:55
  • Thanks, Is there any way to disable the pretty print when converting from CSV to JSON? No. I'm trying also to have the number without the quotes, is this possible? Yes, by specifying type as Int. If you need any specific question, pls raise new OP question. Glad to answer. – Cinchoo May 20 '20 at 00:52
  • 1
    This is a better answer since almost all of the other solutions assume that the only comma's are the separators. In csv's it's common to quote a value that contains the separator. There is a sample further down that does that with this library but I used the sample above and changed ".WithFirstLineHeader()" to ".WithFirstLineHeader().QuoteAllFields()" and it worked perfectly for my test data. That being said, it didn't work if the value contained the line separator but there may be a something to control that too, I just haven't looked for it. Nice job Cinchoo... – Jay13 Apr 30 '21 at 15:45
  • Use `MayContainEOLInData()` to handle line separator in the data. – Cinchoo Apr 30 '21 at 19:07
17

I used Dictionary and returned json using newtonsoft

public string ConvertCsvFileToJsonObject(string path) 
{
    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);
    }

    return JsonConvert.SerializeObject(listObjResult); 
}
Tasso Mello
  • 347
  • 2
  • 5
5
Install Nuget package NewtonSoft.Json
Add reference dll Microsoft.VisualBasic

using System.Linq;
using Newtonsoft.Json;
using Microsoft.VisualBasic.FileIO;
using System.IO;
using System;
using System.Collections.Generic;
using System.Globalization;

namespace Project
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            string CSVpath = @"D:\New Folder\information.csv";
            string analyticsData = ReadFile(CSVpath);
        }

        private static string ReadFile(string filePath)
        {
            string payload = "";
            try
            {
                if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath) && Path.GetExtension(filePath).Equals(".csv", StringComparison.InvariantCultureIgnoreCase))
                {
                    string[] lines = File.ReadAllLines(filePath);

                    if (lines != null && lines.Length > 1)
                    {
                        var headers = GetHeaders(lines.First());
                        payload = GetPayload(headers, lines.Skip(1));
                    }
                }
            }
            catch (Exception exp)
            {
            }
            return payload;
        }

        private static IEnumerable<string> GetHeaders(string data)
        {
            IEnumerable<string> headers = null;

            if (!string.IsNullOrWhiteSpace(data) && data.Contains(','))
            {
                headers = GetFields(data).Select(x => x.Replace(" ", ""));
            }
            return headers;
        }

        private static string GetPayload(IEnumerable<string> headers, IEnumerable<string> fields)
        {
            string jsonObject = "";
            try
            {
                var dictionaryList = fields.Select(x => GetField(headers, x));
                jsonObject = JsonConvert.SerializeObject(dictionaryList);
            }
            catch (Exception ex)
            {
            }
            return jsonObject;
        }

        private static Dictionary<string, string> GetField(IEnumerable<string> headers, string fields)
        {
            Dictionary<string, string> dictionary = null;

            if (!string.IsNullOrWhiteSpace(fields))
            {
                var columns = GetFields(fields);

                if (columns != null && headers != null && columns.Count() == headers.Count())
                {
                    dictionary = headers.Zip(columns, (x, y) => new { x, y }).ToDictionary(item => item.x, item => item.y);
                }
            }
            return dictionary;
        }

        public static IEnumerable<string> GetFields(string line)
        {
            IEnumerable<string> fields = null;
            using (TextReader reader = new StringReader(line))
            {
                using (TextFieldParser parser = new TextFieldParser(reader))
                {
                    parser.TextFieldType = FieldType.Delimited; parser.SetDelimiters(","); fields = parser.ReadFields();
                }
            }
            return fields;
        }
    }
}
Mayer Spitz
  • 2,577
  • 1
  • 20
  • 26
Anand Kishore
  • 111
  • 2
  • 9
3

Taking only a dependency on Newtonsoft.Json, here's a helper method given an array of CSV lines, the first one being the header.

    public static IEnumerable<JObject> CsvToJson(IEnumerable<string> csvLines)
    {
        var csvLinesList = csvLines.ToList();

        var header = csvLinesList[0].Split(',');
        for (int i = 1; i < csvLinesList.Count; i++)
        {
            var thisLineSplit = csvLinesList[i].Split(',');
            var pairedWithHeader = header.Zip(thisLineSplit, (h, v) => new KeyValuePair<string, string>(h, v));

            yield return new JObject(pairedWithHeader.Select(j => new JProperty(j.Key, j.Value)));
        }
    }
bc3tech
  • 1,228
  • 14
  • 27
  • Any guidance on how to turn a `csv` string variable read in from a file as a `string` to an `IEnumerable` collection?` – benhorgen Mar 25 '23 at 16:22
3

I use ChoETL:

using ChoETL;
using System.IO;

public class FromCSVtoJSON
{
    public FromCSVtoJSON()
    {

    }

    public void convertFile(string inputFile, string outputFile)
    {
        using (var writer = new ChoJSONWriter(outputFile))
        {
            using (var reader = new ChoCSVReader(inputFile).WithFirstLineHeader())
            {
                writer.Write(reader);
            }
        }
    }
}
Cinchoo
  • 6,088
  • 2
  • 19
  • 34
Davide Castronovo
  • 1,366
  • 8
  • 21
2

From that same SO answer, there is a link to this post.

CsvToJson extention method

/// <summary>
/// Converts a CSV string to a Json array format.
/// </summary>
/// <remarks>First line in CSV must be a header with field name columns.</remarks>
/// <param name="value"></param>
/// <returns></returns>
public static string CsvToJson(this string value)
{
    // Get lines.
    if (value == null) return null;
    string[] lines = value.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
    if (lines.Length < 2) throw new InvalidDataException("Must have header line.");

    // Get headers.
    string[] headers = lines.First().SplitQuotedLine(new char[] { ',' }, false);

    // Build JSON array.
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("[");
    for (int i = 1; i < lines.Length; i++)
    {
        string[] fields = lines[i].SplitQuotedLine(new char[] { ',', ' ' }, true, '"', false);
        if (fields.Length != headers.Length) throw new InvalidDataException("Field count must match header count.");
        var jsonElements = headers.Zip(fields, (header, field) => string.Format("{0}: {1}", header, field)).ToArray();
        string jsonObject = "{" + string.Format("{0}", string.Join(",", jsonElements)) + "}";
        if (i < lines.Length - 1)
            jsonObject += ",";
        sb.AppendLine(jsonObject);
    }
    sb.AppendLine("]");
    return sb.ToString();
}

There appears to be an issue with where some methods called within the above extension live (see the comments of the original blog post), but it should get you most of the way there.

EDIT Here is another SO answer about splitting a CSV line. You could use one of the suggested regex solutions to create your own SplitQuotedLine method:

public static string SplitQuotedLine(this string value, char separator, bool quotes) {
    // Use the "quotes" bool if you need to keep/strip the quotes or something...
    var s = new StringBuilder();
    var regex = new Regex("(?<=^|,)(\"(?:[^\"]|\"\")*\"|[^,]*)");
    foreach (Match m in regex.Matches(value)) {
        s.Append(m.Value);
    }
    return s.ToString();
}

I did not test the above, so forgive me if I made any errors.

Also, it would appear that Zip is a LINQ extension method, so that takes care of that problem.

Community
  • 1
  • 1
Tim Hobbs
  • 2,017
  • 17
  • 24
  • yes, but SplitQuotedLine - this is a user-defined method which is missing from the blog post – user1427026 May 30 '12 at 21:18
  • Even without seeing what is going on within that method, it is pretty easy to tell it is just splitting up a string. `lines.First().Split(',')` would essentially do the same thing - it likely just tests for any quoted commas and possibly strips the quotes out too. The `Zip` extension may be a bit more to figure out. Like I said, it gets you most of the way there. I guess you are looking for something 100% complete though since you are new to C#, right? – Tim Hobbs May 30 '12 at 21:22
  • Sure, I hope it works out. Like I said, I just posted as an example, I did not try it. It should work, but may require some small tweaks, but no guarantees! :) – Tim Hobbs May 30 '12 at 21:52
  • `SplitQuotedLine` is it `return string []` ? – Rajib Chy Aug 06 '19 at 16:02
2

Here's mine.. It can parse 9k CSV records in centuries. LOL

class CSVTOJSON
{
    public string ConvertToJSON()
    {
        string json = string.Empty;
        string csv = string.Empty;

        using (StreamReader reader = new StreamReader("data.csv"))
        {
            csv = reader.ReadToEnd();
        }

        string[] lines = csv.Split(new string[] { "\n" }, System.StringSplitOptions.None);

        if (lines.Length > 1)
        {
            // parse headers
            string[] headers = lines[0].Split(',');

            StringBuilder sbjson = new StringBuilder();
            sbjson.Clear();
            sbjson.Append("[");

            // parse data
            for (int i = 1; i < lines.Length; i++)
            {
                if (string.IsNullOrWhiteSpace(lines[i])) continue;
                if (string.IsNullOrEmpty(lines[i])) continue;

                sbjson.Append("{");

                string[] data = lines[i].Split(',');

                for (int h = 0; h < headers.Length; h++)
                {
                    sbjson.Append(
                        $"\"{headers[h]}\": \"{data[h]}\"" + (h < headers.Length - 1 ? "," : null)
                    );
                }

                sbjson.Append("}" + (i < lines.Length - 1 ? "," : null));
            }

            sbjson.Append("]");

            json = sbjson.ToString();
        }

        return json;
    }
}

But it works.

console log:

Converting CSV to JSON
CSV has 9486 data
Total duration converting CSV to JSON: 00:00:00.0775373
jaysonragasa
  • 1,076
  • 1
  • 20
  • 40
2

Small variation to the solution by bc3tech i.e. avoiding external dependencies (on Newtonsoft.Json), and instead using System.Text.Json (dotnet core 3+)

public static IEnumerable<string> CsvToJson(string fileName, char delim = '|')
{
    var lines = File.ReadLines(fileName); 
    var hdr = new List<string>(lines.First().Trim().Split(delim));
    foreach (var l in lines.Skip(1).Where(l => (l.Trim() != String.Empty))) 
    {
        var val = l.Trim().Split(delim);
        var ds = hdr.Zip(val, (k, v) => new { k, v }).ToDictionary(x => x.k, x => x.v);
        yield return JsonSerializer.Serialize(ds);
    }
}
KrisKom
  • 21
  • 1
1

I can see most people simply assume parsing CSV file is to simply split comma delimiter between each column, but the following format is still a valid CSV

"aaa","bbb","ccc"
"z, z",yyy,xxx

There is a nice class hidden within Microsoft.VisualBasic.FileIO to handle CSV file format correctly. I combine this with JSON.NET came up with the solution.

   public static string? CsvToJson(string input, string delimiter)
   {
        using (TextFieldParser parser = new TextFieldParser(
                 new MemoryStream(Encoding.UTF8.GetBytes(input))))
        {
            parser.Delimiters = new string[] { delimiter };
            string[]? headers = parser.ReadFields();
            if (headers == null) return null;
            string[]? row;
            string comma = "";
            var sb = new StringBuilder((int)(input.Length * 1.1));
            sb.Append("[");
            while ((row = parser.ReadFields()) != null)
            {
                var dict = new Dictionary<string, object>();
                for (int i = 0; row != null && i < row.Length; i++)
                    dict[headers[i]] = row[i];

                var obj = JsonConvert.SerializeObject(dict);
                sb.Append(comma + obj);
                comma = ",";
            }
            return sb.Append("]").ToString();
        }
    }

Usage

var str = @"Header1,""Header,,2 "",Data3
1,444.00, ""Liang, Jerry""
0,""5,550"",Jerry
";

var json = CsvToJson(str, ",");

Result

[
  {
    "Header1": "1",
    "Header,,2": "444.00",
    "Data3": "Liang, Jerry"
  },
  {
    "Header1": "0441",
    "Header,,2": "5,550",
    "Data3": "Jerry"
  }
]
OKEEngine
  • 888
  • 11
  • 28
0

I looked for the answer for this question finally i solved it by using Dictionary

public static void CreateJsonFromCSV()
{
    string path = "C:\\Users\\xx\\xx\\xx\\xx\\lang.csv";
    string textFilePath = path;
    const Int32 BufferSize = 128;

    using (var fileStream = File.OpenRead(textFilePath))
    using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize))
    {
        String line;
        Dictionary<string, string> jsonRow = new Dictionary<string, string>();

        while ((line = streamReader.ReadLine()) != null)
        {

            string[] parts = line.Split(',');

            string key_ = parts[0];
            string value = parts[1];


            if (!jsonRow.Keys.Contains(key_))
            {
                jsonRow.Add(key_, value );
            }

        }
        var json = new JavaScriptSerializer().Serialize(jsonRow);
        string path_ = "C:\\XX\\XX\\XX\\XX\\XX.csv";
        File.WriteAllText(path_, json);
    }

} 
Dimo
  • 89
  • 1
  • 6
0

Make sure you add the below in web.config before you do parse large csv files.

 <system.web.extensions>
       <scripting>
           <webServices>
               <jsonSerialization maxJsonLength="50000000"/>
           </webServices>
       </scripting>
   </system.web.extensions>
Kurkula
  • 6,386
  • 27
  • 127
  • 202
0

Try this:

 StreamReader sr = new StreamReader(filePath);
 while ((line = sr.ReadLine()) != null)
 {
      //Console.WriteLine(line);
      string[] csv = line.Split(',');
      var dictionary = new Dictionary<string, string>();
      dictionary.Add("dispatching_base_number",csv[0]);
      dictionary.Add("available_vehicles", csv[1]);
      dictionary.Add("vehicles_in_trips", csv[2]);
      dictionary.Add("Cancellations", csv[3]);
      string jsonN = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(dictionary);
      Console.WriteLine("Sending message: {0}",jsonN);
 }
brunorey
  • 2,135
  • 1
  • 18
  • 26
0

Try this and convert CSV to JSON object:

public static List<object> CsvToJson( string body, string[] column ) {
    if ( string.IsNullOrEmpty( body ) ) return null;
    string[] rowSeparators = new string[] { "\r\n" };
    string[] rows = body.Split( rowSeparators, StringSplitOptions.None );
    body = null;
    if ( rows == null || ( rows != null && rows.Length == 0 ) ) return null;
    string[] cellSeparator = new string[] { "," };
    List<object> data = new List<object>( );
    int clen = column.Length;
    rows.Select( row => {
        if ( string.IsNullOrEmpty( row ) ) return row;
        string[] cells = row.Trim( ).Split( cellSeparator, StringSplitOptions.None );
        if ( cells == null ) return row;
        if ( cells.Length < clen ) return row;
        Dictionary<object, object> jrows = new Dictionary<object, object>( );
        for ( int i = 0; i < clen; i++ ) {
            jrows.Add( column[i], cells[i]?.Trim( ) );
        }
        data.Add( jrows );
        return row;
    } ).ToList( );
    rowSeparators = null; rows = null;
    cellSeparator = null;
    return data;
}

var data = CsvToJson("csv_input_str", new string[]{ "column_map" })
string jsonStr = new JavaScriptSerializer { MaxJsonLength = int.MaxValue }.Serialize( data );
Rajib Chy
  • 800
  • 10
  • 22
0

First, load the csv file into datatable and serialize it to Json document. It uses OLEDB Provider that can parse the csv wisely,

Courtesy to Jim Scott, https://stackoverflow.com/a/1050278/6928056

Courtesy to K_B, https://stackoverflow.com/a/2979938/6928056

using System.Data;
using System.Data.OleDb;
using System.Globalization;
using System.IO;
using Newtonsoft.Json;

static string ConvertCsvToJson(string path, bool isFirstRowHeader)
{
    string header = isFirstRowHeader ? "Yes" : "No";

    string pathOnly = Path.GetDirectoryName(path);
    string fileName = Path.GetFileName(path);

    string sql = @"SELECT * FROM [" + fileName + "]";

    using(OleDbConnection connection = new OleDbConnection(
              @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathOnly + 
              ";Extended Properties=\"Text;HDR=" + header + "\""))
    using(OleDbCommand command = new OleDbCommand(sql, connection))
    using(OleDbDataAdapter adapter = new OleDbDataAdapter(command))
    {
        var dataTable = new DataTable();
        dataTable.Locale = CultureInfo.CurrentCulture;
        adapter.Fill(dataTable);
        return JsonConvert.SerializeObject(dataTable, Formatting.Indented);
    }
}
Ashokan Sivapragasam
  • 2,033
  • 2
  • 18
  • 39
0

Simple method to convert flat csv file to a collection of simple json formatted objects. Works with files with header row on the first line. Part of this method was found somewhere else on SO. Add reference to Microsoft.VisualBasic.

using Microsoft.VisualBasic.FileIO;
public static StringBuilder ReadCsv()
    {
        var path = @"X:\...\input.csv";
        using (TextFieldParser csvParser = new TextFieldParser(path))
        {
            csvParser.CommentTokens = new string[] { "#" };
            //Remember to use your own separator
            csvParser.SetDelimiters(new string[] { ";" });
            csvParser.HasFieldsEnclosedInQuotes = false;

            StringBuilder json = new StringBuilder();
            string[] colNames = new string[0];
            string[] fields = new string[0];

            json.Append("[");

            int counter = 0;
            while (!csvParser.EndOfData)
            {
                if (counter == 0)
                {
                    //Read properies' names
                    colNames = csvParser.ReadFields();
                    counter++;
                    Console.WriteLine($"{colNames.Length} columns detected!");
                }
                else
                {
                    // Read current line fields, pointer moves to the next line.
                    // Read the properties' values
                    fields = csvParser.ReadFields();

                    json.Append("{");

                    for (int i = 0; i < colNames.Length; i++)
                    {
                        json.Append($"\"{colNames[i]}\":{TryParse(fields[i])}");
                        if (i != colNames.Length - 1)
                        {
                            json.Append(",");
                        }
                    }
                    json.Append("},");
                    Console.WriteLine($"Writing record nr.: {counter}");
                    counter++;
                }
            }
            json.Length--; //Remove trailing comma
            json.Append("]");
            return json;
        }
    }

string TryParse(string s)
    {
        if (string.IsNullOrEmpty(s)) return "null";
        //Remember to set your decimal character here!
        if (s.Contains('.'))
        {
            double dResult;
            //This works on my computer, could be different on your machine
            if (double.TryParse(s, NumberStyles.AllowDecimalPoint,
                                CultureInfo.InvariantCulture, out dResult))
                return dResult.ToString(CultureInfo.InvariantCulture);
        }
        else
        {
            int intResult;
            if (int.TryParse(s, out intResult))
                return intResult.ToString(CultureInfo.InvariantCulture);
        }
        return "\"" + s + "\"";
    }

This should give you a simple list of json objects.

0

If you are looking for a C# only solution this might work for you. I recently face the same issue and created this method to overcome.

public static string ConvertToJsonStructure(string csvDataAsString, char delimiter = ',', bool hasHeaders = true)
    {
        var output = string.Empty;
        if (string.IsNullOrEmpty(csvDataAsString))
            return "{}";

        var rows = csvDataAsString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
        var headers = hasHeaders ? rows[0].Split(delimiter) : null;
        var colCount = headers?.Length;
        var jsonStart = "{";
        var jsonEnd = "}";

        if (rows.Length > (1 + (hasHeaders ? 1 : 0)))
        {
            jsonStart = "[";
            jsonEnd = "]";
        }

        output = output + jsonStart;

        int startIndex = hasHeaders ? 1 : 0;

        for (int i = startIndex; i < rows.Length; i++)
        {
            var cols = rows[i].Split(delimiter);

            if (colCount == null)
                colCount = cols.Length;

            var tempJson = "{";

            for (int j = 0; j < colCount.Value; j++)
            {
                if (hasHeaders)
                    tempJson = tempJson + $"\"{headers[j]}\":";

                var isNumber = Regex.IsMatch(cols[j], @"^\d + $");
                var val = isNumber ? cols[j] : $"\"{cols[j]}\"";
                tempJson = tempJson + val;

                if (j < colCount.Value - 1)
                    tempJson = tempJson + ",";

            }

            tempJson = tempJson + "}";

            if (i < rows.Length - 1)
                tempJson = tempJson + ",";

            output = output + tempJson;
        }

        output = output + jsonEnd;

        return output;
    }
}

You need to pass your content as string to this method and you can do something like this to read your csv

var csvAsString = File.ReadAllText("TestCsv.csv");

        var result = CsvToJson.ConvertToJsonStructure(csvAsString);
0

For the myriad reasons you're seeing in all these answers, stand on the shoulders of giants and use a Csv Parsing nuget package to pull out the data, then serialize it to JSON using built-in serializers. There is no reason at all to hand-roll this.

bc3tech
  • 1,228
  • 14
  • 27