Search code examples
c#.netcsvhelper

CsvHelper parsing fails for tab delimitted record


I have a Tab delimited file and using CsvHelper to parse it in .Net c# Somehow its failing at 1 record and throws BadData, nothing seems wrong in record, i tried pasting in excel and used text to column, it worked fine.

Code to reproduce error

//add CsvHelper nuget package to project
//Create .txt file with below line and pass path of file into function
//copy text from https://gist.github.com/JitenPatoliya/9f9a15eb388c32f46231aa9fa35dd6e3
//Paste into your text file and try this code

private void TestCSvParser(string fullFilePath)
        {
            try
            {
                string ext = Path.GetExtension(fullFilePath);
                using var reader = new StreamReader(fullFilePath);
                using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
                csv.Configuration.BadDataFound = BadDataFound;
                csv.Configuration.DetectColumnCountChanges = true;
                if (ext.IsContains(".txt"))
                {
                    csv.Configuration.Delimiter = "\t";
                }
                while (csv.Read())
                {
                    var fullrow = csv.Context.RawRecord;
                    var record = csv.Parser.Read();
                }
            }
            catch (Exception ex)
            {

            }
        }

private void BadDataFound(ReadingContext ctx)
        {
         //put debug point here
        }

Thank you and aprreciate you for spending time into this issue


Solution

  • Ok, the problem is that one of your fields contains a ", which is a quotation character. You either have to escape it, or ignore quotes in your file. In the code bellow I'm ignoring. Also, if you'll be using Parser.Read, you shouldn't use csv.Read since it already advances to the next record before reading. So, your code becomes:

    private void TestCSvParser(string fullFilePath)
    {    
        try
        {
            string ext = Path.GetExtension(fullFilePath);
            using var reader = new StreamReader(fullFilePath);
            using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
            csv.Configuration.BadDataFound = BadDataFound;
            csv.Configuration.DetectColumnCountChanges = true;
            if (ext.Contains(".txt"))
            {
                csv.Configuration.Delimiter = "\t";                    
                csv.Configuration.IgnoreQuotes = true;
            }
            string[] record;
            while((record = csv.Parser.Read()) != null)
            {
                var fullrow = csv.Context.RawRecord;
            }                
        }
        catch (Exception ex)
        {
    
        }
    }