Monday, March 19, 2018

How to Import CSVs with .NET Core and C#

Accessing CSV is a common tasks in C# development. On this post, let's review a simple yet elegant solution on how to do it.
One common requirement is to deal with external files, especially CSV files. Because in theory CSV files are simple, developers tend to rush and implement their own parsers. However, it takes a lot of work (and uncountable bugs) to write a good CSV reader/writer. The effort is simply not worth it: you shouldn't repeat yourself.

Luckly, Josh Close has built the excellent CSVHelper for us. Let's test it out.

Importing CSV files with C#

Let's review then a very simple use case to demo how can we import CSVs, parse them to a strongly typed model using CSVHelper.

For this demo, I will be using VS 2017 and the following CSV file:

Now, let's do code!

Step 1: Create a new .Net Core project

So, go and create a new project:

Step 2: Reference the CsvHelper Nupkg to your solution

Next, add a nuget reference to the CsvHelper nupkg to your project and accept the terms.

Step 3: Add the CsvLine model class

Now with my project referencing the CsvHelper package, I still need two more classes. The first one,
I called it CsvLine. This class represents each of the imported records in the csv, apart from the header.

Note: this class name is very anemic. In a production code I wouldn't name it if I needed to use that class elsewhere but for this post, it helps simplifying the explanation.

The code for this class looks like:

Step 4: Add the CsvImportedDemo class

Next, add a class to your project (Project -> Add -> New Item) [or just Alt-Shift-C when selecting your project in Visual Studio's Solution explorer] called CsvImporterDemo. This class will act as the facade of my project containing the logic to orchestrate the execution flow.

CsvImporterDemo will contain a Import method that basically will:
  • open the file;
  • feed csv reader;
  • load all recs on the file with the csv reader;
  • print some of the records

The code for this class looks like:

Yes, you're reading it right. It took only 1 line of code to import that csv [line 23].

Debugging the .NET Core console app

Because I plan to specify the imported file from the command line, I need to provide args to my project before running. This is done on project properties window -> Debug -> add "Application arguments". Ex:

So that when I run my code in debug mode, I get the params that the user is supposed to pass in the command line:

All set! Now, before we run it and see the results, let's add a nice tip.

Tip: Override ToString and use string interpolation

A nice caveat to add for this extremely simple project is to override the ToString method on the CsvLine class. This allows us to format its return when calling the ToString method. A bonus here is to use string interpolation to simplify even more our logic:

Running on Windows

Now, let's run it. From within Visual Studio, just pressing F5 runs in debug mode for me. Here's the output in windows:

We also can run it directly from the terminal (but don't forget to pass the filename) with:
dotnet CsvImporter.dll --file export.csv

Running on Linux

Of course, we almost forgot! Because this is a .net Core app, we can run in Linux. Let's try!? =)

First, we need to publish the application so the dotnet tool builds a folder with all the dependencies. This is done by using the dotnet publish command:

Then, I can easily run it in Linux (my Fedora workstation) with:


We showed some interesting things on this demo:
  • how to import CSV files the simple way. For more complex scenarios, check this link;
  • publishing .NET Core apps;
  • some programming techniques such as string interpolation, method overrides, programming concepts and some design patterns were introduced;
  • how to run .NET Core apps from the console;
  • run to run run a .NET Core app in Linux.

Source Code

The source for this project can be found here.

See Also

For more posts on .NET Core, please click here.
Do you have any comment or suggestion about this post? Please contact me @BrunoHilden