/// <summary> /// Returns an object filled with values from the given CSV row. Properties of T have to have CsvFieldAttributes for mapping to work /// </summary> private T GetRecord <T>(Dictionary <string, CsvPropertyMap> propertyMap, int rowNumber, string[] csvRow) where T : ICsvRow, new() { T obj = new T() { RowNumber = rowNumber }; if (propertyMap.Count > csvRow.Length) { throw new Exception(MissingElementsMessage(csvRow.Length, propertyMap.Count)); } CsvPropertyMap propertyWithMaxIndex = propertyMap.Values.OrderByDescending(x => x.Index).First(); if (propertyWithMaxIndex.Index >= csvRow.Length) { throw new Exception(InvalidIndexMappingMessage(propertyWithMaxIndex)); } foreach (KeyValuePair <string, CsvPropertyMap> item in propertyMap) { var inputValue = csvRow[item.Value.Index]; if (!string.IsNullOrWhiteSpace(inputValue)) { // convert string to proper value type eg. int object value = GetValueFromString(item.Key, item.Value.PropertyType, csvRow[item.Value.Index], rowNumber); obj.GetType().GetProperty(item.Key).SetValue(obj, value); } } return(obj); }
/// <summary> /// Returns a dictionary with values from property attributes - key is the Property Name /// </summary> private static Dictionary <string, CsvPropertyMap> GetPropertyMappingConfig <T>() { var mapping = new Dictionary <string, CsvPropertyMap>(); PropertyInfo[] props = typeof(T).GetProperties(); foreach (PropertyInfo prop in props) { CsvFieldAttribute csvAttr = prop.GetCustomAttribute <CsvFieldAttribute>(false); if (csvAttr != null) { var cfg = new CsvPropertyMap(csvAttr.Index, csvAttr.ColumnName ?? prop.Name, prop.Name, prop.PropertyType); mapping.Add(prop.Name, cfg); } } ValidatePropertyMappingConfig <T>(mapping); return(mapping); }
private static string InvalidIndexMappingMessage(CsvPropertyMap property) => $"missing value of '{property.ColumnName}' with index '{property.Index}'.";