I've a problem to read this file with CSVHelper for example, how can I use a ShouldSkipRecord to not receive a exception? I've tried to keep all my Map columns Optional but doesn't work.
Class:
public class WheelProsAccessoriesInventoryItem : WheelProsBaseInventoryItem
{
public override string PartNumber { get; set; }
public override string PartDescription { get; set; }
public override string Brand { get; set; }
public string CapHardwareDescription { get; set; }
public string CapScrewQuantity { get; set; }
public string CapWrench { get; set; }
public string CapStyleDescription { get; set; }
public string ImageURL { get; set; }
public override string TotalQOH { get; set; }
public override string Msrp { get; set; }
public override string Map { get; set; }
public override string RunDate { get; set; }
public override string StockLa1 { get; set; }
public override string num1015 { get; set; }
public override string num1019 { get; set; }
public override string num1022 { get; set; }
public override string num1028 { get; set; }
public override string StockLa2 { get; set; }
public override string num1036 { get; set; }
public override string num1071 { get; set; }
public override string num1072 { get; set; }
public override string num1082 { get; set; }
public override string StockLa3 { get; set; }
public override string StockTX { get; set; }
public override string num1092 { get; set; }
public override string StockLangley { get; set; }
public override string StockToronto { get; set; }
public int LineNumber { get; set; }
}
}
MAP:
public class WheelProsAccessoriesInventoryItemMap : ClassMap<WheelProsAccessoriesInventoryItem>
{**
public WheelProsAccessoriesInventoryItemMap()
{
Map(m => m.PartNumber).Name("PartNumber");
Map(m => m.Brand).Name("Brand");
Map(m => m.PartDescription).Name("PartDescription");
Map(m => m.CapHardwareDescription).Name("CapHardwareDescription").Optional();
Map(m => m.CapScrewQuantity).Name("CapScrewQuantity").Optional();
Map(m => m.CapWrench).Name("CapWrench").Optional();
Map(m => m.CapStyleDescription).Name("CapStyleDescription").Optional();
Map(m => m.ImageURL).Name("ImageURL");
Map(m => m.TotalQOH).Name("TotalQOH");
Map(m => m.Msrp).Name("MSRP");
Map(m => m.Map).Name("MAP");
Map(m => m.RunDate).Name("RunDate");
// StockWarehouses
// 1011 – Stock LA1 Warehouse
Map(m => m.StockLa1).Name("1011");
// 1031 - Stock LA2 Riverside
Map(m => m.StockLa2).Name("1031");
// 1085 – Stock LA3 LA Warehouse Support
Map(m => m.StockLa3).Name("1085");
// 1086 - StockTX Dallas Warehouse
Map(m => m.StockTX).Name("1086");
// 4033 - Stock Langley/Vancouver
Map(m => m.StockLangley).Name("4033");
// 4035 - Stock Toronto
Map(m => m.StockToronto).Name("4035");
// 1088 - Stock US - Atlanta Logistics Center
Map(m => m.num1088).Name("1088");
Map(m => m.num1015).Name("1015").Optional();
Map(m => m.num1019).Name("1019").Optional();
Map(m => m.num1022).Name("1022").Optional();
Map(m => m.num1028).Name("1028").Optional();
Map(m => m.num1036).Name("1036").Optional();
Map(m => m.num1071).Name("1071").Optional();
Map(m => m.num1072).Name("1072").Optional();
// Map(m => m.LineNumber).Convert(record => record.Row.Parser.Row);
}
}
}
Read Method:
public static IEnumerable<T> GetRecords<T, TMap>(string filename, bool hasFrenchChars = false)
where T : class
where TMap : ClassMap<T>
{
var errorRecsCollection = new List<string>();
var malformedRow = false;
using (var streamReader = new StreamReader(filename))
{
using (var csvReader = new CsvReader(streamReader, CultureInfo.InvariantCulture))
{
csvReader.Context.RegisterClassMap<TMap>();
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = ",",
HasHeaderRecord = true,
Encoding = hasFrenchChars ? Encoding.GetEncoding("ISO-8859-1") : Encoding.UTF8,
IgnoreBlankLines = true,
MissingFieldFound = null,
BadDataFound = context =>
{
malformedRow = true;
errorRecsCollection.Add(context.RawRecord);
}
};
// var rowNumber = csvReader.Parser.Row;
return csvReader.GetRecords<T>().ToList();
}
}
}
How I need to do to ignore the files? I've tried to add this config below but doesn't works.
This is how I handle bad records (all code in the same method)
var isRecordBad = false;
csv.Configuration.BadDataFound = context =>
{
isRecordBad = true;
bad.Add(context.RawRecord);
};
var records = csv.GetRecords<dynamic>(); //You can still use your type and map, dynamic is sometimes just easier for complicated mappings
foreach (var record in records)
{
var dictionary = record as IDictionary<string, object>;
if (!isRecordBad)
{
//keep the data - add to list
}
isRecordBad = false;
}
If you decide to go the dynamic
type route you can also write less code and just check for the keys in the converted dictionary
when generating the WheelProsAccessoriesInventoryItem
object