Search code examples
c#asp.netcsvdynamicfilehelpers

Edit dynamic records at runtime


I have an ASP.NET application editing files uploaded on the server at runtime.

I have to handle CSV files so I chose the FileHelpers library.

As I don't know what will be the headers of the CSV, I use this library to create a custom class dynamically at runtime and fill a DataTable with the headers and records.

Then, the application adds a new column to the DataTable and the values generated for each row.

I need the new values to be written in the CSV file so I need to edit the records at runtime without knowing the class format.

Here is the snippet of what I have done so far, but if you could give me an hint on how to perform this, I will really appreciate :)

List<object> values = new List<object>();

var classBuilder = new DelimitedClassBuilder("CSVClass", delimiter.ToString(), dataTable);

classBuilder.LastField.FieldOptional = true;

Engine = new FileHelperEngine(classBuilder.CreateRecordClass());

string lastFieldName = classBuilder.LastField.FieldName;
i = 0;
foreach (dynamic record in Engine.ReadFile(filePath))
{
    record.Test = newValues[i]; //This line is working as the new column is named "Test" but if the column name changes, it throws an exception of course

    values.Add(record);

    i++;
}

Engine.WriteFile(filePath, values);

Solution

  • I finally found my way through this.

    The solution was to use the CsvEngine class and his DataTableToCsv method.

    For the curious ones, here is the final code:

    List values = new List();

    string header = null;
    
    DataRow row = dataTable.NewRow();
    
    int i = 0;
    foreach (var value in newValues)
    {
        string newValue = value;
    
        if (i == 0)
        {
    
            List<object> headers = valuesDictionnary[0].ToList<Object>();
            int count = 1;
            while (true)
    
                if (headers.Contains(newValue))
                {
                    newValue = value + "_" + count;
                    count++;
                }
                else
                    break;
    
            header = newValue;
            dataTable.Columns.Add(newValue);
    
            foreach(DataColumn column in dataTable.Columns)
            {
                row[column.ColumnName] = column.ColumnName;
            }
    
            dataTable.Rows.InsertAt(row, 0);
        }
    
        dataTable.Rows[i][header] = newValue;
        i++;
    }
    
    CsvEngine.DataTableToCsv(dataTable, filePath, new CsvOptions("CSVOptions", delimiter, filePath));
    
    dataTable.Rows.RemoveAt(0);