Hello,
Recently I've make a program to import a CSV file, it's contains error checks, normalizations and another stuffs. You can adapt this code for your purposes, the imported CSV columns are described in class Order -> method: InitializeFieldDesc().
using System;
using System.IO;
using System.Collections.Generic;
public class ImportCSV
{
List<Order> orders;
List<Order> invalidOrders;
Logger logger;
public ImportCSV(string filePath)
{
logger = new Logger();
orders = new List<Order>();
invalidOrders = new List<Order>();
LoadOrders(filePath);
}
#region Load orders
private void LoadOrders(string filePath)
{
if (File.Exists(filePath))
{
GetOrdersFromFile(filePath);
}
else
{
throw new FileNotFoundException("File not found");
}
}
private void GetOrdersFromFile(string filePath)
{
logger.setActiveOrder(-1);
logger.AddInfo("Opening file: " + filePath);
try
{
string[] lines = File.ReadAllLines(filePath);
for (int i = 0; i < lines.Length; i++)
{
logger.setActiveOrder(i);
Order tempOrder = new Order(ref logger);
logger.AddInfo("Mapping a string into order's object. Line nº: " + i.ToString());
tempOrder.LoadOrder(i, lines[i]);
if (!tempOrder.hasErrors)
{
orders.Add(tempOrder);
}
else
{
invalidOrders.Add(tempOrder);
logger.AddInfo("Invalid data detection in line nº: " + i.ToString());
}
}
}
catch (Exception exc)
{
logger.setActiveOrder(-1);
logger.AddException(exc);
}
logger.setActiveOrder(-1);
logger.AddInfo(string.Format("Ends of orders load process. Valid orders: {0}. Invalid orders: {1}.",
orders.Count.ToString(), invalidOrders.Count.ToString()));
}
#endregion
#region Public properties get valid & invalid orders
public List<Order> getValidOrders
{
get { return orders; }
}
public List<Order> getInvalidOrders
{
get { return invalidOrders; }
}
#endregion
#region Manage Order
public class OrderField
{
public string fieldName;
public DataCheck.ChecksTypes checkType;
public System.Type dataType;
public bool mandatory;
public object value = null;
}
public class Order
{
private Logger logger;
List<OrderField> fieldDesc;
private DataCheck check;
public Order(ref Logger _logger)
{
logger = _logger;
check = new DataCheck(ref logger);
InitializefieldDesc();
}
private void InitializefieldDesc()
{
fieldDesc = new List<OrderField>();
fieldDesc.Add(new OrderField()
{
fieldName = "OrderId",
checkType = DataCheck.ChecksTypes.PositiveInteger,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "DealId",
checkType = DataCheck.ChecksTypes.PositiveInteger,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "Email",
checkType = DataCheck.ChecksTypes.Email,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "Street",
checkType = DataCheck.ChecksTypes.Street,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "City",
checkType = DataCheck.ChecksTypes.String,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "State",
checkType = DataCheck.ChecksTypes.State,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "ZipCode",
checkType = DataCheck.ChecksTypes.NO_CHECK,
dataType = typeof(Int32),
mandatory = true
});
fieldDesc.Add(new OrderField()
{
fieldName = "CreditCard",
checkType = DataCheck.ChecksTypes.NO_CHECK,
dataType = typeof(Int32),
mandatory = true
});
}
public void LoadOrder(int idOrder, string orderLine)
{
string[] orderParts = orderLine.Split(',');
if (orderParts.Length != fieldDesc.Count)
{
logger.AddInvalidDataError("Order line malformed, item counts: " + orderParts.Length);
}
else
{
for (int i = 0; i < fieldDesc.Count; i++)
{
check.FieldDataCheck(fieldDesc[i], orderParts[i]);
}
}
}
#region Public properties: field mapping by name
public int OrderId { get { return (int)fieldDesc[0].value; } }
public int DealId { get { return (int)fieldDesc[1].value; } }
public string Email { get { return (string)fieldDesc[2].value; } }
public string Street { get { return (string)fieldDesc[3].value; } }
public string City { get { return (string)fieldDesc[4].value; } }
public string State { get { return (string)fieldDesc[5].value; } }
public string ZipCode { get { return (string)fieldDesc[6].value; } }
public string CreditCard { get { return (string)fieldDesc[7].value; } }
#endregion
public bool hasErrors
{
get { return logger.thereisInvalidData; }
}
}
#endregion
#region Utilities
public class Logger
{
internal enum LogType
{
INVALID_DATA,
EXCEPTION,
INFO
}
internal struct LogItem
{
public LogType logType;
public string message;
}
private Dictionary<int, List<LogItem>> Log;
private int activeOrderId;
public Logger()
{
Log = new Dictionary<int, List<LogItem>>();
}
internal List<LogItem> getOrderLog(int orderId)
{
if (!Log.ContainsKey(activeOrderId))
Log.Add(activeOrderId, new List<LogItem>());
return Log[activeOrderId];
}
internal void setActiveOrder(int orderId)
{
activeOrderId = orderId;
}
public void AddInfo(string message)
{
getOrderLog(activeOrderId).Add(new LogItem()
{
logType = LogType.INFO,
message = message
});
}
public void AddException(Exception exception)
{
getOrderLog(activeOrderId).Add(new LogItem()
{
logType = LogType.EXCEPTION,
message = exception.Message
});
}
public void AddInvalidDataError(string message)
{
getOrderLog(activeOrderId).Add(new LogItem()
{
logType = LogType.INVALID_DATA,
message = message
});
}
public bool thereisExceptions
{
get
{
return getOrderLog(activeOrderId).Exists(i => i.logType == LogType.EXCEPTION);
}
}
public bool thereisInvalidData
{
get
{
return getOrderLog(activeOrderId).Exists(i => i.logType == LogType.INVALID_DATA);
}
}
}
public class DataCheck
{
public enum ChecksTypes
{
String,
PositiveInteger,
Email,
Street,
State,
NO_CHECK
}
Normalize normalize;
Logger logger;
public DataCheck(ref Logger _logger)
{
logger = _logger;
normalize = new Normalize();
}
public void FieldDataCheck(OrderField datafield, string value)
{
if (datafield.checkType == ChecksTypes.PositiveInteger)
{
PositiveInteger(datafield, value);
}
else if (datafield.checkType == ChecksTypes.Email)
{
Email(datafield, value);
}
else if (datafield.checkType == ChecksTypes.State)
{
State(datafield, value);
}
else if (datafield.checkType == ChecksTypes.Street)
{
Street(datafield, value);
}
else if (datafield.checkType == ChecksTypes.String)
{
ChkString(datafield, value);
}
else
{
datafield.value = value;
}
}
#region Check functions
private void PositiveInteger(OrderField dataField, string value)
{
int temp = 0;
if (!int.TryParse(value, out temp))
{
logger.AddInvalidDataError(string.Format("Invalid {0}: is not an integer", dataField.fieldName.ToString()));
}
else if (temp < 0)
{
logger.AddInvalidDataError(string.Format("Invalid {0}: is not positive integer", dataField.fieldName.ToString()));
}
else
{
dataField.value = temp;
}
}
private void ChkString(OrderField dataField, string value)
{
value = value.Trim().ToLower();
if ((dataField.mandatory) && (value == ""))
{
logger.AddInvalidDataError(string.Format("Invalid {0}: empty string", dataField.fieldName.ToString()));
}
else
{
dataField.value = value;
}
}
private void Email(OrderField dataField, string Email)
{
ChkString(dataField, Email);
bool invalidFormat = (dataField.value.ToString() == "");
if (!invalidFormat)
{
Email = dataField.value.ToString();
invalidFormat = (Email.IndexOf("@") <= 0);
}
if (!invalidFormat)
{
invalidFormat = (Email.Split(new char[] { '@' }).Length != 2);
}
if (!invalidFormat)
{
invalidFormat = (Email.LastIndexOf(".") < Email.IndexOf("@"));
}
if (!invalidFormat)
{
dataField.value = normalize.Email(Email);
}
else
{
logger.AddInvalidDataError("Invalid email format");
}
}
private void State(OrderField dataField, string value)
{
ChkString(dataField, value);
if (dataField.value.ToString() != "")
dataField.value = normalize.State(dataField.value.ToString());
}
private void Street(OrderField dataField, string value)
{
ChkString(dataField, value);
if (dataField.value.ToString() != "")
dataField.value = normalize.Street(dataField.value.ToString());
}
#endregion
public bool ThereIsErrors
{
get { return logger.thereisInvalidData; }
}
}
public class Normalize
{
public string Email(string Email)
{
var aux = Email.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
if (aux.Length > 1)
{
var atIndex = aux[0].IndexOf("+", StringComparison.Ordinal);
aux[0] = atIndex < 0 ? aux[0].Replace(".", "") : aux[0].Replace(".", "").Remove(atIndex);
return string.Join("@", new string[] { aux[0], aux[1] });
}
else return aux[0];
}
public string Street(string Street)
{
Dictionary<string, string> replaces = new Dictionary<string, string>();
replaces.Add("st.", "street");
replaces.Add("rd.", "road");
foreach (string replace in replaces.Keys)
{
Street = Street.Replace(replace, replaces[replace]);
}
return Street;
}
public string State(string State)
{
Dictionary<string, string> replaces = new Dictionary<string, string>();
replaces.Add("il", "illinois");
replaces.Add("ca", "california");
replaces.Add("ny", "new york");
foreach (string replace in replaces.Keys)
{
State = State.Replace(replace, replaces[replace]);
}
return State;
}
}
#endregion
}