Strongly typed parsing of CSV-files
up vote
2
down vote
favorite
So after about an hour's worth of pulling my hair in desperation, I decided to follow the advice from, like, everybody in here and not implement my own CSV-parser.
So I went with FileHelpers instead.
But I am having a bit of trouble using it correctly.
My CSV-file looks something like this:
50382018,50319368,eBusiness Manager,IT02,3350_FIB4,IT,2480
50370383,50373053,CRM Manager,IT01,3200_FIB3,xyz,2480
50320067,50341107,"VP, Business Information Officer",IT03,3200_FI89,xyz,2480
50299061,50350088,Project Expert,IT02,8118_FI09,abc,2480
My need for FileHelpers (and, specifically CsvEngine
) is in line 3 - notice third column enclosed in quotes since it has an internal comma (which is otherwise used as delimiter).
My code to read the file is this:
var co = new FileHelpers.Options.CsvOptions("Employee", columnDeliminator, 7);
var ce = new CsvEngine(co);
var records = ce.ReadFile(pathToCSVFile);
It works fine - sort of. It correctly parses the lines and recognizes the values with enclosed delimiters.
But.
The return value of the ReadFile()
-method is object
. And the contents of it appears to be some kind of dynamic type.
It looks something like this - where the columns are named "Field_1", "Field_2" etc.
I have created a "data class" intended to hold the parsed lines It looks like this:
public class Employee
{
public string DepartmentPosition;
public string ParentDepartmentPosition;
public string JobTitle;
public string Role;
public string Location;
public string NameLocation;
public string EmployeeStatus;
}
Is there a way to have FileHelpers' CsvEngine
class to return strongly typed data?
If I could just use the "basic" parser of FileHelpers, I could use this code:
var engine = new FileHelperEngine<Employee>();
var records = engine.ReadFile("Input.txt");
Is there a way to have CsvEngine
return instances of my "Employee" class? Or do I have to write my own mapping code to support this?
c# csv text-parsing filehelpers
add a comment |
up vote
2
down vote
favorite
So after about an hour's worth of pulling my hair in desperation, I decided to follow the advice from, like, everybody in here and not implement my own CSV-parser.
So I went with FileHelpers instead.
But I am having a bit of trouble using it correctly.
My CSV-file looks something like this:
50382018,50319368,eBusiness Manager,IT02,3350_FIB4,IT,2480
50370383,50373053,CRM Manager,IT01,3200_FIB3,xyz,2480
50320067,50341107,"VP, Business Information Officer",IT03,3200_FI89,xyz,2480
50299061,50350088,Project Expert,IT02,8118_FI09,abc,2480
My need for FileHelpers (and, specifically CsvEngine
) is in line 3 - notice third column enclosed in quotes since it has an internal comma (which is otherwise used as delimiter).
My code to read the file is this:
var co = new FileHelpers.Options.CsvOptions("Employee", columnDeliminator, 7);
var ce = new CsvEngine(co);
var records = ce.ReadFile(pathToCSVFile);
It works fine - sort of. It correctly parses the lines and recognizes the values with enclosed delimiters.
But.
The return value of the ReadFile()
-method is object
. And the contents of it appears to be some kind of dynamic type.
It looks something like this - where the columns are named "Field_1", "Field_2" etc.
I have created a "data class" intended to hold the parsed lines It looks like this:
public class Employee
{
public string DepartmentPosition;
public string ParentDepartmentPosition;
public string JobTitle;
public string Role;
public string Location;
public string NameLocation;
public string EmployeeStatus;
}
Is there a way to have FileHelpers' CsvEngine
class to return strongly typed data?
If I could just use the "basic" parser of FileHelpers, I could use this code:
var engine = new FileHelperEngine<Employee>();
var records = engine.ReadFile("Input.txt");
Is there a way to have CsvEngine
return instances of my "Employee" class? Or do I have to write my own mapping code to support this?
c# csv text-parsing filehelpers
Will the CSV file have headers? Have you looked at using CsvHelper?
– Nkosi
Nov 11 at 22:44
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
So after about an hour's worth of pulling my hair in desperation, I decided to follow the advice from, like, everybody in here and not implement my own CSV-parser.
So I went with FileHelpers instead.
But I am having a bit of trouble using it correctly.
My CSV-file looks something like this:
50382018,50319368,eBusiness Manager,IT02,3350_FIB4,IT,2480
50370383,50373053,CRM Manager,IT01,3200_FIB3,xyz,2480
50320067,50341107,"VP, Business Information Officer",IT03,3200_FI89,xyz,2480
50299061,50350088,Project Expert,IT02,8118_FI09,abc,2480
My need for FileHelpers (and, specifically CsvEngine
) is in line 3 - notice third column enclosed in quotes since it has an internal comma (which is otherwise used as delimiter).
My code to read the file is this:
var co = new FileHelpers.Options.CsvOptions("Employee", columnDeliminator, 7);
var ce = new CsvEngine(co);
var records = ce.ReadFile(pathToCSVFile);
It works fine - sort of. It correctly parses the lines and recognizes the values with enclosed delimiters.
But.
The return value of the ReadFile()
-method is object
. And the contents of it appears to be some kind of dynamic type.
It looks something like this - where the columns are named "Field_1", "Field_2" etc.
I have created a "data class" intended to hold the parsed lines It looks like this:
public class Employee
{
public string DepartmentPosition;
public string ParentDepartmentPosition;
public string JobTitle;
public string Role;
public string Location;
public string NameLocation;
public string EmployeeStatus;
}
Is there a way to have FileHelpers' CsvEngine
class to return strongly typed data?
If I could just use the "basic" parser of FileHelpers, I could use this code:
var engine = new FileHelperEngine<Employee>();
var records = engine.ReadFile("Input.txt");
Is there a way to have CsvEngine
return instances of my "Employee" class? Or do I have to write my own mapping code to support this?
c# csv text-parsing filehelpers
So after about an hour's worth of pulling my hair in desperation, I decided to follow the advice from, like, everybody in here and not implement my own CSV-parser.
So I went with FileHelpers instead.
But I am having a bit of trouble using it correctly.
My CSV-file looks something like this:
50382018,50319368,eBusiness Manager,IT02,3350_FIB4,IT,2480
50370383,50373053,CRM Manager,IT01,3200_FIB3,xyz,2480
50320067,50341107,"VP, Business Information Officer",IT03,3200_FI89,xyz,2480
50299061,50350088,Project Expert,IT02,8118_FI09,abc,2480
My need for FileHelpers (and, specifically CsvEngine
) is in line 3 - notice third column enclosed in quotes since it has an internal comma (which is otherwise used as delimiter).
My code to read the file is this:
var co = new FileHelpers.Options.CsvOptions("Employee", columnDeliminator, 7);
var ce = new CsvEngine(co);
var records = ce.ReadFile(pathToCSVFile);
It works fine - sort of. It correctly parses the lines and recognizes the values with enclosed delimiters.
But.
The return value of the ReadFile()
-method is object
. And the contents of it appears to be some kind of dynamic type.
It looks something like this - where the columns are named "Field_1", "Field_2" etc.
I have created a "data class" intended to hold the parsed lines It looks like this:
public class Employee
{
public string DepartmentPosition;
public string ParentDepartmentPosition;
public string JobTitle;
public string Role;
public string Location;
public string NameLocation;
public string EmployeeStatus;
}
Is there a way to have FileHelpers' CsvEngine
class to return strongly typed data?
If I could just use the "basic" parser of FileHelpers, I could use this code:
var engine = new FileHelperEngine<Employee>();
var records = engine.ReadFile("Input.txt");
Is there a way to have CsvEngine
return instances of my "Employee" class? Or do I have to write my own mapping code to support this?
c# csv text-parsing filehelpers
c# csv text-parsing filehelpers
asked Nov 11 at 16:46
Jesper Lund Stocholm
87221229
87221229
Will the CSV file have headers? Have you looked at using CsvHelper?
– Nkosi
Nov 11 at 22:44
add a comment |
Will the CSV file have headers? Have you looked at using CsvHelper?
– Nkosi
Nov 11 at 22:44
Will the CSV file have headers? Have you looked at using CsvHelper?
– Nkosi
Nov 11 at 22:44
Will the CSV file have headers? Have you looked at using CsvHelper?
– Nkosi
Nov 11 at 22:44
add a comment |
4 Answers
4
active
oldest
votes
up vote
0
down vote
The documentation worked for me for a one simple way:
First in your class, it needs a couple decorators:
Edit Use the FieldQuoted decorator to parse anything in quotes and ignore the included comma
[DelimitedRecord(",")]
class Person
{
[FieldQuoted]
public string Name { get; set; }
[FieldConverter(ConverterKind.Int32)]
public int Age { get; set; }
public string State { get; set; }
}
DelimitedRecord
for the class and the expected delimiter (this could be a problem if things change later.
and FieldConverter for it appears anything other than string.
Then change your reading method slightly:
var fhr = new FileHelperEngine<Person>();
var readLines = fhr.ReadFile(pathToFile);
and then it works, strongly typed:
foreach(var person in readLines)
{
Console.WriteLine(person.Name);
}
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
2
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot useCsvEngine
. You would need to do the mapping yourself. UsingFileHelperEngine<Employee>
is the best approach, but you need to decorate the class with[DelimitedRecord(",")]
and decorate the JobTitle property with[FieldQuoted(QuoteMode.OptionalForRead)]
.
– shamp00
Nov 11 at 20:22
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
add a comment |
up vote
0
down vote
Using CsvHelper as a viable alternative and assuming the CSV file has no headers,
a mapping can be created for the Employee
class like
public sealed class EmployeeClassMap : ClassMap<Employee> {
public EmployeeClassMap() {
Map(_ => _.Location).Index(0);
Map(_ => _.NameLocation).Index(1);
Map(_ => _.JobTitle).Index(2);
//...removed for brevity
}
}
Where the index is mapped to a respective property on the strongly typed object model.
To use this mapping, you need to register the mapping in the configuration.
using (var textReader = new StreamReader(pathToCSVFile)) {
var csv = new CsvReader(textReader);
csv.Configuration.RegisterClassMap<EmployeeClassMap>();
var records = csv.GetRecords<Employee>();
//...
}
add a comment |
up vote
0
down vote
accepted
@shamp00 has the correct answer - and I also found it at FileHelper escape delimiter .
I took my model class and decorated each property on it as suggested:
(I probably don't need to decorate all properties, but it works for now)
[DelimitedRecord((","))]
public class Employee
{
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string DepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string ParentDepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string JobTitle;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Role;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Location;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string NameLocation;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string EmployeeStatus;
}
Now I just need this code:
TextReader reader = new StreamReader(contents);
var engine = new FileHelperEngine<Employee>()
{
Options = { IgnoreFirstLines = 1 }
};
var myRecords = engine.ReadStream(reader);
add a comment |
up vote
-1
down vote
If this lib not work, you can also try to use built-in .Net CSV parser TextFieldParser. For ex: https://coding.abel.nu/2012/06/built-in-net-csv-parser/
ADDED:
For types (with auto convert):
static void run()
{
// split with any lib line of CSV
string line = new string{"john", "doe", "201"};
// needed prop names of class
string propNames = "fname|lname|room".Split('|');
Person p = new Person();
parseLine<Person>(p, line, propNames);
}
static void parseLine<T>(T t, string line, string propNames)
{
for(int i = 0;i<propNames.Length;i++)
{
string sprop = propNames[i];
PropertyInfo prop = t.GetType().GetProperty(sprop);
object val = Convert.ChangeType(line[i], prop.PropertyType);
prop.SetValue(t, val );
}
}
class Person
{
public string fname{get;set;}
public string lname{get;set;}
public int room {get;set;}
}
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
can't write comments :(
– AndrewF
Nov 11 at 18:14
add a comment |
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
The documentation worked for me for a one simple way:
First in your class, it needs a couple decorators:
Edit Use the FieldQuoted decorator to parse anything in quotes and ignore the included comma
[DelimitedRecord(",")]
class Person
{
[FieldQuoted]
public string Name { get; set; }
[FieldConverter(ConverterKind.Int32)]
public int Age { get; set; }
public string State { get; set; }
}
DelimitedRecord
for the class and the expected delimiter (this could be a problem if things change later.
and FieldConverter for it appears anything other than string.
Then change your reading method slightly:
var fhr = new FileHelperEngine<Person>();
var readLines = fhr.ReadFile(pathToFile);
and then it works, strongly typed:
foreach(var person in readLines)
{
Console.WriteLine(person.Name);
}
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
2
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot useCsvEngine
. You would need to do the mapping yourself. UsingFileHelperEngine<Employee>
is the best approach, but you need to decorate the class with[DelimitedRecord(",")]
and decorate the JobTitle property with[FieldQuoted(QuoteMode.OptionalForRead)]
.
– shamp00
Nov 11 at 20:22
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
add a comment |
up vote
0
down vote
The documentation worked for me for a one simple way:
First in your class, it needs a couple decorators:
Edit Use the FieldQuoted decorator to parse anything in quotes and ignore the included comma
[DelimitedRecord(",")]
class Person
{
[FieldQuoted]
public string Name { get; set; }
[FieldConverter(ConverterKind.Int32)]
public int Age { get; set; }
public string State { get; set; }
}
DelimitedRecord
for the class and the expected delimiter (this could be a problem if things change later.
and FieldConverter for it appears anything other than string.
Then change your reading method slightly:
var fhr = new FileHelperEngine<Person>();
var readLines = fhr.ReadFile(pathToFile);
and then it works, strongly typed:
foreach(var person in readLines)
{
Console.WriteLine(person.Name);
}
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
2
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot useCsvEngine
. You would need to do the mapping yourself. UsingFileHelperEngine<Employee>
is the best approach, but you need to decorate the class with[DelimitedRecord(",")]
and decorate the JobTitle property with[FieldQuoted(QuoteMode.OptionalForRead)]
.
– shamp00
Nov 11 at 20:22
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
add a comment |
up vote
0
down vote
up vote
0
down vote
The documentation worked for me for a one simple way:
First in your class, it needs a couple decorators:
Edit Use the FieldQuoted decorator to parse anything in quotes and ignore the included comma
[DelimitedRecord(",")]
class Person
{
[FieldQuoted]
public string Name { get; set; }
[FieldConverter(ConverterKind.Int32)]
public int Age { get; set; }
public string State { get; set; }
}
DelimitedRecord
for the class and the expected delimiter (this could be a problem if things change later.
and FieldConverter for it appears anything other than string.
Then change your reading method slightly:
var fhr = new FileHelperEngine<Person>();
var readLines = fhr.ReadFile(pathToFile);
and then it works, strongly typed:
foreach(var person in readLines)
{
Console.WriteLine(person.Name);
}
The documentation worked for me for a one simple way:
First in your class, it needs a couple decorators:
Edit Use the FieldQuoted decorator to parse anything in quotes and ignore the included comma
[DelimitedRecord(",")]
class Person
{
[FieldQuoted]
public string Name { get; set; }
[FieldConverter(ConverterKind.Int32)]
public int Age { get; set; }
public string State { get; set; }
}
DelimitedRecord
for the class and the expected delimiter (this could be a problem if things change later.
and FieldConverter for it appears anything other than string.
Then change your reading method slightly:
var fhr = new FileHelperEngine<Person>();
var readLines = fhr.ReadFile(pathToFile);
and then it works, strongly typed:
foreach(var person in readLines)
{
Console.WriteLine(person.Name);
}
edited Nov 11 at 21:05
answered Nov 11 at 17:19
Austin T French
2,46611328
2,46611328
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
2
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot useCsvEngine
. You would need to do the mapping yourself. UsingFileHelperEngine<Employee>
is the best approach, but you need to decorate the class with[DelimitedRecord(",")]
and decorate the JobTitle property with[FieldQuoted(QuoteMode.OptionalForRead)]
.
– shamp00
Nov 11 at 20:22
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
add a comment |
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
2
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot useCsvEngine
. You would need to do the mapping yourself. UsingFileHelperEngine<Employee>
is the best approach, but you need to decorate the class with[DelimitedRecord(",")]
and decorate the JobTitle property with[FieldQuoted(QuoteMode.OptionalForRead)]
.
– shamp00
Nov 11 at 20:22
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
Hi @Austin, you realize that you are suggesting that I try something, that I specifically wrote in my question as not being possible? 😀.
– Jesper Lund Stocholm
Nov 11 at 19:22
2
2
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot use
CsvEngine
. You would need to do the mapping yourself. Using FileHelperEngine<Employee>
is the best approach, but you need to decorate the class with [DelimitedRecord(",")]
and decorate the JobTitle property with [FieldQuoted(QuoteMode.OptionalForRead)]
.– shamp00
Nov 11 at 20:22
@Austin's answer looks correct to me. If you want the engine to return an array of concrete classes, you cannot use
CsvEngine
. You would need to do the mapping yourself. Using FileHelperEngine<Employee>
is the best approach, but you need to decorate the class with [DelimitedRecord(",")]
and decorate the JobTitle property with [FieldQuoted(QuoteMode.OptionalForRead)]
.– shamp00
Nov 11 at 20:22
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
Out of curiosity, @JesperLundStocholm why does that not work as a solution? Also, I tried to guess why it didn't, the "Quoted word, with comma" in which case I showed how to get around that.
– Austin T French
Nov 11 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
@AustinTFrench I cannot use your suggestion since it chokes on line three with the enclosed delimiter. However - I found the solution and managed to augment your suggestion. See below :-)
– Jesper Lund Stocholm
Nov 12 at 21:07
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
Odd, the enclosed delimiter worked fine for me with the update from yesterday...
– Austin T French
Nov 12 at 23:02
add a comment |
up vote
0
down vote
Using CsvHelper as a viable alternative and assuming the CSV file has no headers,
a mapping can be created for the Employee
class like
public sealed class EmployeeClassMap : ClassMap<Employee> {
public EmployeeClassMap() {
Map(_ => _.Location).Index(0);
Map(_ => _.NameLocation).Index(1);
Map(_ => _.JobTitle).Index(2);
//...removed for brevity
}
}
Where the index is mapped to a respective property on the strongly typed object model.
To use this mapping, you need to register the mapping in the configuration.
using (var textReader = new StreamReader(pathToCSVFile)) {
var csv = new CsvReader(textReader);
csv.Configuration.RegisterClassMap<EmployeeClassMap>();
var records = csv.GetRecords<Employee>();
//...
}
add a comment |
up vote
0
down vote
Using CsvHelper as a viable alternative and assuming the CSV file has no headers,
a mapping can be created for the Employee
class like
public sealed class EmployeeClassMap : ClassMap<Employee> {
public EmployeeClassMap() {
Map(_ => _.Location).Index(0);
Map(_ => _.NameLocation).Index(1);
Map(_ => _.JobTitle).Index(2);
//...removed for brevity
}
}
Where the index is mapped to a respective property on the strongly typed object model.
To use this mapping, you need to register the mapping in the configuration.
using (var textReader = new StreamReader(pathToCSVFile)) {
var csv = new CsvReader(textReader);
csv.Configuration.RegisterClassMap<EmployeeClassMap>();
var records = csv.GetRecords<Employee>();
//...
}
add a comment |
up vote
0
down vote
up vote
0
down vote
Using CsvHelper as a viable alternative and assuming the CSV file has no headers,
a mapping can be created for the Employee
class like
public sealed class EmployeeClassMap : ClassMap<Employee> {
public EmployeeClassMap() {
Map(_ => _.Location).Index(0);
Map(_ => _.NameLocation).Index(1);
Map(_ => _.JobTitle).Index(2);
//...removed for brevity
}
}
Where the index is mapped to a respective property on the strongly typed object model.
To use this mapping, you need to register the mapping in the configuration.
using (var textReader = new StreamReader(pathToCSVFile)) {
var csv = new CsvReader(textReader);
csv.Configuration.RegisterClassMap<EmployeeClassMap>();
var records = csv.GetRecords<Employee>();
//...
}
Using CsvHelper as a viable alternative and assuming the CSV file has no headers,
a mapping can be created for the Employee
class like
public sealed class EmployeeClassMap : ClassMap<Employee> {
public EmployeeClassMap() {
Map(_ => _.Location).Index(0);
Map(_ => _.NameLocation).Index(1);
Map(_ => _.JobTitle).Index(2);
//...removed for brevity
}
}
Where the index is mapped to a respective property on the strongly typed object model.
To use this mapping, you need to register the mapping in the configuration.
using (var textReader = new StreamReader(pathToCSVFile)) {
var csv = new CsvReader(textReader);
csv.Configuration.RegisterClassMap<EmployeeClassMap>();
var records = csv.GetRecords<Employee>();
//...
}
answered Nov 11 at 23:17
Nkosi
107k16113182
107k16113182
add a comment |
add a comment |
up vote
0
down vote
accepted
@shamp00 has the correct answer - and I also found it at FileHelper escape delimiter .
I took my model class and decorated each property on it as suggested:
(I probably don't need to decorate all properties, but it works for now)
[DelimitedRecord((","))]
public class Employee
{
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string DepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string ParentDepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string JobTitle;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Role;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Location;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string NameLocation;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string EmployeeStatus;
}
Now I just need this code:
TextReader reader = new StreamReader(contents);
var engine = new FileHelperEngine<Employee>()
{
Options = { IgnoreFirstLines = 1 }
};
var myRecords = engine.ReadStream(reader);
add a comment |
up vote
0
down vote
accepted
@shamp00 has the correct answer - and I also found it at FileHelper escape delimiter .
I took my model class and decorated each property on it as suggested:
(I probably don't need to decorate all properties, but it works for now)
[DelimitedRecord((","))]
public class Employee
{
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string DepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string ParentDepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string JobTitle;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Role;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Location;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string NameLocation;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string EmployeeStatus;
}
Now I just need this code:
TextReader reader = new StreamReader(contents);
var engine = new FileHelperEngine<Employee>()
{
Options = { IgnoreFirstLines = 1 }
};
var myRecords = engine.ReadStream(reader);
add a comment |
up vote
0
down vote
accepted
up vote
0
down vote
accepted
@shamp00 has the correct answer - and I also found it at FileHelper escape delimiter .
I took my model class and decorated each property on it as suggested:
(I probably don't need to decorate all properties, but it works for now)
[DelimitedRecord((","))]
public class Employee
{
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string DepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string ParentDepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string JobTitle;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Role;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Location;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string NameLocation;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string EmployeeStatus;
}
Now I just need this code:
TextReader reader = new StreamReader(contents);
var engine = new FileHelperEngine<Employee>()
{
Options = { IgnoreFirstLines = 1 }
};
var myRecords = engine.ReadStream(reader);
@shamp00 has the correct answer - and I also found it at FileHelper escape delimiter .
I took my model class and decorated each property on it as suggested:
(I probably don't need to decorate all properties, but it works for now)
[DelimitedRecord((","))]
public class Employee
{
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string DepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string ParentDepartmentPosition;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string JobTitle;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Role;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string Location;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string NameLocation;
[FieldQuoted('"', QuoteMode.OptionalForBoth)]
public string EmployeeStatus;
}
Now I just need this code:
TextReader reader = new StreamReader(contents);
var engine = new FileHelperEngine<Employee>()
{
Options = { IgnoreFirstLines = 1 }
};
var myRecords = engine.ReadStream(reader);
answered Nov 12 at 21:13
Jesper Lund Stocholm
87221229
87221229
add a comment |
add a comment |
up vote
-1
down vote
If this lib not work, you can also try to use built-in .Net CSV parser TextFieldParser. For ex: https://coding.abel.nu/2012/06/built-in-net-csv-parser/
ADDED:
For types (with auto convert):
static void run()
{
// split with any lib line of CSV
string line = new string{"john", "doe", "201"};
// needed prop names of class
string propNames = "fname|lname|room".Split('|');
Person p = new Person();
parseLine<Person>(p, line, propNames);
}
static void parseLine<T>(T t, string line, string propNames)
{
for(int i = 0;i<propNames.Length;i++)
{
string sprop = propNames[i];
PropertyInfo prop = t.GetType().GetProperty(sprop);
object val = Convert.ChangeType(line[i], prop.PropertyType);
prop.SetValue(t, val );
}
}
class Person
{
public string fname{get;set;}
public string lname{get;set;}
public int room {get;set;}
}
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
can't write comments :(
– AndrewF
Nov 11 at 18:14
add a comment |
up vote
-1
down vote
If this lib not work, you can also try to use built-in .Net CSV parser TextFieldParser. For ex: https://coding.abel.nu/2012/06/built-in-net-csv-parser/
ADDED:
For types (with auto convert):
static void run()
{
// split with any lib line of CSV
string line = new string{"john", "doe", "201"};
// needed prop names of class
string propNames = "fname|lname|room".Split('|');
Person p = new Person();
parseLine<Person>(p, line, propNames);
}
static void parseLine<T>(T t, string line, string propNames)
{
for(int i = 0;i<propNames.Length;i++)
{
string sprop = propNames[i];
PropertyInfo prop = t.GetType().GetProperty(sprop);
object val = Convert.ChangeType(line[i], prop.PropertyType);
prop.SetValue(t, val );
}
}
class Person
{
public string fname{get;set;}
public string lname{get;set;}
public int room {get;set;}
}
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
can't write comments :(
– AndrewF
Nov 11 at 18:14
add a comment |
up vote
-1
down vote
up vote
-1
down vote
If this lib not work, you can also try to use built-in .Net CSV parser TextFieldParser. For ex: https://coding.abel.nu/2012/06/built-in-net-csv-parser/
ADDED:
For types (with auto convert):
static void run()
{
// split with any lib line of CSV
string line = new string{"john", "doe", "201"};
// needed prop names of class
string propNames = "fname|lname|room".Split('|');
Person p = new Person();
parseLine<Person>(p, line, propNames);
}
static void parseLine<T>(T t, string line, string propNames)
{
for(int i = 0;i<propNames.Length;i++)
{
string sprop = propNames[i];
PropertyInfo prop = t.GetType().GetProperty(sprop);
object val = Convert.ChangeType(line[i], prop.PropertyType);
prop.SetValue(t, val );
}
}
class Person
{
public string fname{get;set;}
public string lname{get;set;}
public int room {get;set;}
}
If this lib not work, you can also try to use built-in .Net CSV parser TextFieldParser. For ex: https://coding.abel.nu/2012/06/built-in-net-csv-parser/
ADDED:
For types (with auto convert):
static void run()
{
// split with any lib line of CSV
string line = new string{"john", "doe", "201"};
// needed prop names of class
string propNames = "fname|lname|room".Split('|');
Person p = new Person();
parseLine<Person>(p, line, propNames);
}
static void parseLine<T>(T t, string line, string propNames)
{
for(int i = 0;i<propNames.Length;i++)
{
string sprop = propNames[i];
PropertyInfo prop = t.GetType().GetProperty(sprop);
object val = Convert.ChangeType(line[i], prop.PropertyType);
prop.SetValue(t, val );
}
}
class Person
{
public string fname{get;set;}
public string lname{get;set;}
public int room {get;set;}
}
edited Nov 11 at 21:54
answered Nov 11 at 18:09
AndrewF
333
333
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
can't write comments :(
– AndrewF
Nov 11 at 18:14
add a comment |
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
can't write comments :(
– AndrewF
Nov 11 at 18:14
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
This really is a comment, not much of answer (or maybe a link only answer)
– Austin T French
Nov 11 at 18:12
can't write comments :(
– AndrewF
Nov 11 at 18:14
can't write comments :(
– AndrewF
Nov 11 at 18:14
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53250936%2fstrongly-typed-parsing-of-csv-files%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Will the CSV file have headers? Have you looked at using CsvHelper?
– Nkosi
Nov 11 at 22:44