0

I'm working with the great FileHelpers library (version 2.9.9). However I've been stuck for some hours now and I'm not able to work this issue out. I would like to load my file into an array of my CustomerClass object. I would like to change the order of the fields dynamically utilizing the DelimitedClassBuilder. I found an answer here on Stackoverflow which shows how to do it https://stackoverflow.com/a/8833322/767926. I'm not able to do it even following that answer. However it works fine if I just use the class directly with the FileHelperEngine instead of DelimitedClassBuilder. Could somebody please help me out here?

This is the object i would like to create an array of from the csv file:

[DelimitedRecord(";")]
public class CustomerClass
{
    public string CustomerId;

    public string FirstName;

    public string LastName;
}

This is the code I'm using to create the array:

public void ReadFile()
{
    DelimitedClassBuilder cb = new DelimitedClassBuilder("CustomerClass", ";");
    cb.AddField("CustomerId", typeof(string));
    cb.AddField("FirstName", typeof(string));
    cb.AddField("LastName", typeof(string));

    FileHelperEngine engine = new FileHelperEngine(cb.CreateRecordClass());
    engine.ErrorMode = ErrorMode.IgnoreAndContinue;

    string filename = @"C:\temp\customerfile.csv";

    DataTable dt = engine.ReadFileAsDT(filename); // Works fine
    object[] test = engine.ReadFile(filename) as object[]; // Works fine

    CustomerClass[] customers = engine.ReadFile(filename) as CustomerClass[]; // Returns null (probably because the 'cast' is invalid, see line below)
    customers = (CustomerClass[])engine.ReadFile(filename); // Throws InvalidCastException (Unable to cast object of type 'CustomerClass[]' to type 'MyNamespace.CustomerClass[]'.)
}

This is the file contents:

CustomerId;FirstName;LastName

1;James;Brown

2;Robert;Miller

3;David;Green

Community
  • 1
  • 1
jmelhus
  • 1,100
  • 2
  • 12
  • 27
  • Is there more than one `CustomerClass` in your project, in different namespaces? – David Crowell Jun 18 '14 at 14:29
  • What is the result if you use `var customers = engine.ReadFile(filename);`. What type does `customers` resolve to? – Daniel Kelley Jun 18 '14 at 14:34
  • And what are the types inside of the array? They will obviously be `object`, but what type is stored in them? – Daniel Kelley Jun 18 '14 at 14:48
  • The type didnt resolve to object it resolved to CustomerClass (but a different CustomerClass than my CustomerClass since this one is constructed dynamically with the DelimitedClassBuilder). It contains 4 objects. The object names are CustomerId, FirstName and LastName. – jmelhus Jun 18 '14 at 14:55

2 Answers2

0

Try the fully qualified class name:

DelimitedClassBuilder cb = new DelimitedClassBuilder("MyNamespace.CustomerClass", ";");

David Crowell
  • 3,405
  • 18
  • 27
  • I've tried that. That throws an exception: "The string 'MyNamespace.CustomerClass' not is a valid .NET identifier". I've also tried to use cb.NameSpace = "MyNamespace.CustomerClass", this throws an InvalidCastException as well... – jmelhus Jun 18 '14 at 14:43
  • Is CustomerClass in the same project? If not, you need to specify the assembly also. – David Crowell Jun 18 '14 at 14:49
  • CustomerClass is within the same project. – jmelhus Jun 18 '14 at 14:51
  • I don't know then. I tried looking up source for the library, but it's blocked here at work. – David Crowell Jun 18 '14 at 14:52
0

Based on the comments you have provided I'd suggest using the following:

var customers = engine.ReadFile(filename)
                      .Cast<*type of the class coming back from ReadFile*>()
                      .Select(c => new MyNamespace.CustomerClass()
                                       {
                                            CustomerId = c.CustomerId,
                                            FirstName = c.FirstName,
                                            LastName = c.LastName
                                       })
                      .ToArray();

You will need to provide the type of the class returned from engine.ReadFile to the call to Cast. The call to Select will then create an instance of your CustomerClass for each customer returned.

Daniel Kelley
  • 7,191
  • 5
  • 39
  • 48
  • This throws an invalidcast as well: Unable to cast object of type 'CustomerClass' to type 'MyNamespace.CustomerClass'. As for the void this is just a simple example i constructed, the method looks quite different. I just wanted to make sure this small simple example worked... – jmelhus Jun 18 '14 at 14:58
  • Just to be clear, `CustomerClass` is coming out of the call to `ReadFile` and `MyNamespace.CustomerClass` is what you want? – Daniel Kelley Jun 18 '14 at 15:02
  • Yes that is correct. I tried to add the correct namespace to the cb.NameSpace property but that gives an invalid cast as well. – jmelhus Jun 18 '14 at 15:06
  • Thanks for the provided solution, I know there are workarounds for my problem, I was looking for a solution utilizing the FileHelpers library since when googling around there seems to be other people that have managed to set up such a solution... – jmelhus Jun 18 '14 at 15:15
  • Thank you for your new suggestion! I tried it, but this generates an invalidcastexception as well unfortunately. For the moment I'm accessing the data with reflection in my array object. – jmelhus Jun 22 '14 at 09:47