NHSISL.CsvHelperClient 2.0.0

dotnet add package NHSISL.CsvHelperClient --version 2.0.0
                    
NuGet\Install-Package NHSISL.CsvHelperClient -Version 2.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NHSISL.CsvHelperClient" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NHSISL.CsvHelperClient" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="NHSISL.CsvHelperClient" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NHSISL.CsvHelperClient --version 2.0.0
                    
#r "nuget: NHSISL.CsvHelperClient, 2.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NHSISL.CsvHelperClient@2.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NHSISL.CsvHelperClient&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=NHSISL.CsvHelperClient&version=2.0.0
                    
Install as a Cake Tool

NHSISL - CsvHelperClient

The Standard The Standard - COMPLIANT NuGet NuGet Downloads

Introduction

CsvHelperClient is a .NET, Standard-compliant wrapper around the popular CsvHelper library. It exposes a clean, async-first API for mapping CSV data to strongly typed .NET objects and vice versa, with built-in support for custom field mappings, optional headers, and trailing-comma control.

Features

  • ✅ Stream-based — works directly with Stream, keeping memory usage low even for large files
  • ✅ Fully async — IAsyncEnumerable<T> for reading, ValueTask for writing
  • ✅ Header control — include or omit header rows when reading and writing
  • ✅ Custom field mappings — map CSV column indices to object properties by name
  • ✅ Trailing comma support — optionally append a trailing comma to each row
  • ✅ Cancellation support — all methods accept a CancellationToken
  • ✅ Structured exceptions — clear validation and dependency exceptions for reliable error handling

Installation

Install the package from NuGet:

dotnet add package NHSISL.CsvHelperClient

Or search for NHSISL.CsvHelperClient in the Visual Studio NuGet Package Manager.

Quick Start

1. Define your model

public class Car
{
    public string Make { get; set; }
    public string Model { get; set; }
    public int Year { get; set; }
    public string Color { get; set; }
}

2. Instantiate the client

CsvClient implements IAsyncDisposable, so use it inside an await using block or manage its lifetime via dependency injection.

await using var csvClient = new CsvClient();

Reading CSV Data

Map CSV to objects (with header row)

When your CSV file contains a header row whose column names match your model's property names, simply pass hasHeaderRecord: true:

string csv = """
    Make,Model,Year,Color
    Toyota,Corolla,2022,White
    Ford,Focus,2021,Blue
    """;

byte[] csvBytes = Encoding.UTF8.GetBytes(csv);
using var inputStream = new MemoryStream(csvBytes);

await using var csvClient = new CsvClient();

await foreach (Car car in csvClient.MapCsvToObjectAsync<Car>(
    data: inputStream,
    hasHeaderRecord: true))
{
    Console.WriteLine($"{car.Year} {car.Make} {car.Model} ({car.Color})");
}

Map CSV to objects (no header, with custom field mappings)

When there is no header row, or the column order differs from your model, supply a fieldMappings dictionary that maps each property name to its zero-based column index:

// CSV columns: Color(0), Year(1), Model(2), Make(3)
string csv = """
    White,2022,Corolla,Toyota
    Blue,2021,Focus,Ford
    """;

byte[] csvBytes = Encoding.UTF8.GetBytes(csv);
using var inputStream = new MemoryStream(csvBytes);

var fieldMappings = new Dictionary<string, int>
{
    { nameof(Car.Make),  3 },
    { nameof(Car.Model), 2 },
    { nameof(Car.Year),  1 },
    { nameof(Car.Color), 0 }
};

await using var csvClient = new CsvClient();

await foreach (Car car in csvClient.MapCsvToObjectAsync<Car>(
    data: inputStream,
    hasHeaderRecord: false,
    fieldMappings: fieldMappings))
{
    Console.WriteLine($"{car.Year} {car.Make} {car.Model} ({car.Color})");
}

Writing CSV Data

Map objects to CSV (with header row)

var cars = new List<Car>
{
    new Car { Make = "Toyota", Model = "Corolla", Year = 2022, Color = "White" },
    new Car { Make = "Ford",   Model = "Focus",   Year = 2021, Color = "Blue"  }
};

using var outputStream = new MemoryStream();

await using var csvClient = new CsvClient();

await csvClient.MapObjectToCsvAsync(
    @object: cars,
    outputStream: outputStream,
    addHeaderRecord: true);

string csvOutput = Encoding.UTF8.GetString(outputStream.ToArray());
Console.WriteLine(csvOutput);
// Make,Model,Year,Color
// Toyota,Corolla,2022,White
// Ford,Focus,2021,Blue

Map objects to CSV (no header)

await csvClient.MapObjectToCsvAsync(
    @object: cars,
    outputStream: outputStream,
    addHeaderRecord: false);

Map objects to CSV with custom column order

Use fieldMappings to control the column order. Each entry maps a property name to its zero-based output column index:

// Output order: Color(0), Year(1), Model(2), Make(3)
var fieldMappings = new Dictionary<string, int>
{
    { nameof(Car.Make),  3 },
    { nameof(Car.Model), 2 },
    { nameof(Car.Year),  1 },
    { nameof(Car.Color), 0 }
};

await csvClient.MapObjectToCsvAsync(
    @object: cars,
    outputStream: outputStream,
    addHeaderRecord: false,
    fieldMappings: fieldMappings);

Map objects to CSV with a trailing comma

Some downstream systems expect every row to end with a comma. Enable this with shouldAddTrailingComma:

await csvClient.MapObjectToCsvAsync(
    @object: cars,
    outputStream: outputStream,
    addHeaderRecord: true,
    shouldAddTrailingComma: true);

API Reference

ICsvClient

Method Description
MapCsvToObjectAsync<T>(Stream, bool, Dictionary<string,int>, bool?, CancellationToken) Reads a CSV stream and yields each row as an instance of T.
MapObjectToCsvAsync<T>(List<T>, Stream, bool, Dictionary<string,int>, bool?, CancellationToken) Serialises a list of T objects into the provided output stream as CSV.
MapCsvToObjectAsync parameters
Parameter Type Default Description
data Stream The CSV input stream. Must not be null.
hasHeaderRecord bool true if the first row is a header.
fieldMappings Dictionary<string, int> null Maps property names to zero-based column indices. When null, property names are matched against the header row.
headerValidated bool? true Controls CsvHelper's built-in header validation.
cancellationToken CancellationToken default Token to cancel the async enumeration.
MapObjectToCsvAsync parameters
Parameter Type Default Description
@object List<T> The list of objects to serialise. Must not be null.
outputStream Stream The stream to write CSV output to. Must not be null.
addHeaderRecord bool true to write a header row as the first line.
fieldMappings Dictionary<string, int> null Maps property names to zero-based output column indices.
shouldAddTrailingComma bool? false true to append a trailing comma to every row.
cancellationToken CancellationToken default Token to cancel the async write.

Error Handling

CsvHelperClient surfaces errors through a structured exception hierarchy so you can handle specific failure modes precisely:

Exception When thrown
CsvHelperClientValidationException Invalid arguments were supplied (e.g. a null stream or null object list).
CsvHelperClientDependencyException An unexpected error occurred in an underlying dependency.
CsvHelperClientServiceException An unexpected error occurred within the service layer.

Example:

try
{
    await foreach (var car in csvClient.MapCsvToObjectAsync<Car>(
        data: inputStream,
        hasHeaderRecord: true))
    {
        Console.WriteLine(car.Make);
    }
}
catch (CsvHelperClientValidationException ex)
{
    Console.WriteLine($"Validation error: {ex.Message}");
}
catch (CsvHelperClientDependencyException ex)
{
    Console.WriteLine($"Dependency error: {ex.Message}");
}

How to Contribute

If you want to contribute to this project, please review the following documents to gain an understanding of the patterns and practices used in building this package:

To report a bug, please open a GitHub issue with as much detail as possible. If you'd like to contribute, feel free to pick up any open issue and submit a pull request with your changes.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (4)

Showing the top 4 NuGet packages that depend on NHSISL.CsvHelperClient:

Package Downloads
ISL.Providers.ReIdentification.OfflineFileSources

ISL.Providers.ReIdentification.OfflineFileSources provides a re-identification implementation for offline use i.e. for acceptance tests where we would use a CSV file to control and manage test outcomes.

ISL.Providers.ReIdentification.DemoData

ISL.Providers.ReIdentification.DemoData provides a re-identification implementation for test purposes.

ISL.Providers.Captcha.GoogleReCaptcha

ISL.Providers.Captcha.GoogleReCaptcha provides a provider wrapper implementation of the Google ReCaptcha service.

ISL.Providers.PDS.FHIR

ISL.Providers.PDS.FHIR provides a provider wrapper implementation of the PDS FHIR service.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
2.0.0 79 5/5/2026
1.1.0 5,046 2/14/2025
1.0.0.1 1,513 12/2/2024
0.0.0.5 1,321 11/13/2024
0.0.0.4 181 11/13/2024
0.0.0.3 2,763 5/10/2024
0.0.0.2 231 5/9/2024
0.0.0.1 163 5/2/2024

A major breaking change to allow large file handling.