I am trying to use CsvHelper to read a csv file with a few optional properties. Whenever I read the csv, I end up with the error message: CsvHelper.MissingFieldException: Field at index '6' does not exist. You can ignore missing fields by setting MissingFieldFound to null. Below is my simple Program and the TagModel I am comparing:
// Using Directive
using System;
using System.Globalization;
using ProjectName;
using CsvHelper;
using CsvHelper.Configuration;
internal class Program
{
public static void Main(string[] args)
{
//Determine filepath for the input.csv file
string inputFile = @"C:\Users\kaden.hansen\Desktop\Huntsman\CPBC14.csv";
//Initialize CSVHelper NuGet package tools
using (var reader = new StreamReader(inputFile)) //Set reader to read the inputFile
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
csv.Context.Configuration.MissingFieldFound = null;
var tags = csv.GetRecords<TagModel>(); //Retrieve records to "tags" IEnumarable
try
{
foreach (var tag in tags)
{
Console.WriteLine(tag.TagName);
}
} catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
Console.WriteLine("Finished reading CSV!");
}
}
And the Tag Model:
// Using Directive
using CsvHelper.Configuration.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ProjectName
{
public class TagModel
{
// Determine Properties (or "columns") returned by the CSV File.
[Name("Hierarchical Name")] //This is the name of the property as it appears in the CSV file row 1.
[Default("")] //This sets a default value for when the field returns as empty.
public string? HierarchicalName { get; set; } // This determines the declaration name that the script will use to access the property, including its type.
[Name("Strategyname")]
[Default("")]
public string? StrategyName { get; set; }
[Name("Tagname")]
[Default("")]
public string? TagName { get; set; }
[Name("Type")]
[Default("")]
public string? Type { get; set; }
[Name("Attribute")]
[Default("")]
public string? Attribute { get; set; }
[Name("Value")]
[Default("")]
public string? Value { get; set; }
[Name("IA Reference")]
[Default("")]
[Optional]
public string? IAReference { get; set; }
}
}
I have included the suggestion listed in the error message: csv.Context.Configuration.MissingFieldFound = null;. I also made sure to make the properties nullable with the string? in the TagModel class. I included [Optional] on the property that tends to throw the error. With all of these, the same error shows in my catch statement. When I removed the "IAReference" property, it read each TagName up to the first row in the csv that was missing the "Value" Property. I concluded that it handles missing properties just fine as long as it isn't the final property in the index.
I am fairly new to C# so it could be some syntax issue, but any help is greatly appreciated!
Starting with version 20.0, the
MissingFieldFoundmust be set on theCsvConfigurationand then passed into theCsvReaderconstructor.It isn't necessary to make the properties nullable
string?and[optional]just means it is optional to include the property in the CSV header. Your issue is theIAReferencehas been included in the header, but if there is no data for it, the last comma is missing.Incorrect CSV
Correct CSV
Solution