NHSISL.CsvHelperClient 3.1.0

dotnet add package NHSISL.CsvHelperClient --version 3.1.0
                    
NuGet\Install-Package NHSISL.CsvHelperClient -Version 3.1.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="3.1.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NHSISL.CsvHelperClient" Version="3.1.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 3.1.0
                    
#r "nuget: NHSISL.CsvHelperClient, 3.1.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@3.1.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=3.1.0
                    
Install as a Cake Addin
#tool nuget:?package=NHSISL.CsvHelperClient&version=3.1.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
3.1.0 2,966 6/1/2026
2.0.0 391 5/5/2026
1.1.0 8,159 2/14/2025
1.0.0.1 1,537 12/2/2024
0.0.0.5 1,350 11/13/2024
0.0.0.4 200 11/13/2024
0.0.0.3 2,797 5/10/2024
0.0.0.2 258 5/9/2024
0.0.0.1 185 5/2/2024

A major breaking change to allow large file handling.