Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you implement (and null) BadDataFound

Based on the instructions in Getting Started with CsvHelper, I have the following code except for the csv.Configuration.BadDataFound line:

using (var csv = new CsvReader(tr, CultureInfo.InvariantCulture))
        {
            List<string> badPeople = new List<string>();
            csv.Configuration.BadDataFound = context => badPeople.Add(context.RawRecord);
            try
            {
                var people = csv.GetRecords<Person>();
                var count = people.Count();
                response = await Http.PostAsJsonAsync("api/people/batch", people);
                Message = $"{response}: {selectedFile.Count} file uploaded";
            }
            catch (Exception ex)
            {
                Message = ex.Message;
            }
        }

I configured the BadDataFound line based on suggestions from the following:

  • Handling bad CSV records in CsvHelper
  • CSVHelper: logging errors when BadDataException is thrown
  • CSVHelper BadDataFound in a valid csv and numerous others.

In the CsvHelper.Configuration documentation it states:

Gets or sets the function that is called when bad field data is found. A field has bad data if it contains a quote and the field is not quoted (escaped). You can supply your own function to do other things like logging the issue instead of throwing an exception. Arguments: context

I keep getting the error that BadDataFound does not have a setter, and based on what I saw when looking at the code on GitHub, that makes sense. The error message I get when I run without the BadDataFOund line states that one can ignore the BadDataFound by nulling it.

To complicate matters, there is also no "RawRecord" in the context that I can find.

How do I get this to work?

like image 408
PirateQueen Avatar asked Jan 21 '26 09:01

PirateQueen


1 Answers

In Version 20.0.0, Josh "Changed CsvConfiguration to a read only record to eliminate threading issues." You need to create the configuration ahead of time and pass it into CsvReader/CsvWriter.

RawRecord is now on the parser.

I did, however, notice that it created a record even if there was bad data and it entered the RawRecord twice into badPeople.

void Main()
{
    var badPeople = new List<string>();
    var Message = string.Empty;
    var people = new List<Person>();
    
    var config = new CsvConfiguration(CultureInfo.InvariantCulture)
    {
        BadDataFound = arg => badPeople.Add(arg.Context.Parser.RawRecord)
    };

    using (var tr = new StringReader("Id,FirstName,LastName\n1,Foo,Bar\n2,Foo\"Bar,Baz\n3,Foo\"Baz,Bar"))
    using (var csv = new CsvReader(tr, config))
    {       
        try
        {
            people = csv.GetRecords<Person>().ToList();
            var count = people.Count();
        }
        catch (Exception ex)
        {
            Message = ex.Message;
        }
    }
    people.Dump();
    badPeople.Dump();
}

public class Person 
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
like image 127
David Specht Avatar answered Jan 23 '26 10:01

David Specht



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!