Reputation: 765
I am using Valum's AJAX File Uploader to upload the csv file. The code to initialize it is :
$(document).ready(function () {
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
// path to server-side upload script
action: 'handlers/PhoneNumberListHandler.ashx',
buttonTitle: 'Upload Document',
buttonText: ' Upload',
allowedExtensions: ['csv'],
sizeLimit: 1024000, // max size
});
});
<div id="file-uploader"></div>
In c# handler class I have written the following code so far:
HttpRequest request = context.Request;
byte[] buffer = new byte[request.ContentLength];
Stream inputStream;
string fileName;
inputStream = request.InputStream;
fileName = request["qqfile"];
using (var reader = new StreamReader(inputStream))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';'); // gives some abstract characters
}
}
My csv file have three columns Phone, Firstname, Lastname where first column is compulsory and rest are optional.
I am now stuck as I am not able to read the .csv file. Can someone please help me and suggest how can I read a csv file content from the stream or is there any other way to do it? I want to extract the csv content and save each line separately in database table.
Update: I made changes in saving the csv file and now the content look like this:
PhoneNumber,FirstName,LastName
11111,Taj,Mahal
22222,Oberai,
33333,,Lake Palace
44444,,
Modified the above code:
using (var reader = new StreamReader(inputStream))
{
List<string> listA = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(values[0]);
}
}
I want to get the individual value of the columns and here I am getting a full line in one string. To get individual value I have to further split it with "," and get the values. I want to know is there a better way to do this?
Upvotes: 0
Views: 2166
Reputation: 1820
Converting CSV file to model with reflection. First of all you could create model and set attributes with Name of CSV columns. like this:
public class UserInfo
{
[CSVColumn(ImportName = "FirstName"]
public string FirstName { get; set; }
[CSVColumn(ImportName = "LastName"]
public string LastName { get; set; }
[CSVColumn(ImportName = "PhoneNumber"]
public string PhoneNumber { get; set; }
}
Other steps are reading first line for getting data about columns and based on property attributes of model set data from scv row to each model property:
List<UserInfo> users = new List<UserInfo>();
using (var reader = new StreamReader(inputStream))
{
//read first line with headers
var metaDataLine = reader.ReadLine() ?? "";
//get array with headers
string[] csvMetada = metaDataLine.Split(',');
while (!reader.EndOfStream)
{
// create model based on string data and columns metadata with columns
UserInfo newModel = ConvertCSVToEntity(reader.ReadLine() ?? "", csvMetada);
users.add(newModel);
}
}
converting method string csv row to model :
public UserInfo convertCSVToEntity(string line, string[] csvMetada)
{
var values = line.Split(',');
UserInfo newRecord = ConvertorHelper.ConvertCSVToEntity<UserInfo>(values, csvMetada);
return newRecord;
}
public static T ConvertCSVToEntity<T>(string[] csvData, string[] csvMetada) where T : new()
{
T returnEntity = new T();
var properties = returnEntity.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var eachProperty in properties)
{
var csvAttribute = eachProperty.GetCustomAttribute(typeof(CSVColumn)) as CSVColumn;
if (csvAttribute != null)
{
int csvIndex = Array.IndexOf(csvMetada, csvAttribute.ImportName);
if (csvIndex > -1)
{
var csvValue = csvData[csvIndex];
object setValue = null;
try
{
setValue = string.IsNullOrEmpty(csvValue) && eachProperty.PropertyType != typeof(string) ? Activator.CreateInstance(eachProperty.PropertyType) : Convert.ChangeType(csvValue, eachProperty.PropertyType, ParseCulture);
}
catch (Exception e)
{
}
}
}
return returnEntity;
}
Attributes class
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
public class CSVColumn : Attribute
{
public string ImportName { set; get; }
public CSVColumn() { }
public CSVColumn(string _import)
{
this.ImportName = _import;
}
}
Upvotes: 1