Shane32.CsvLinq 1.0.1

Prefix Reserved
dotnet add package Shane32.CsvLinq --version 1.0.1
                    
NuGet\Install-Package Shane32.CsvLinq -Version 1.0.1
                    
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="Shane32.CsvLinq" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shane32.CsvLinq" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Shane32.CsvLinq" />
                    
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 Shane32.CsvLinq --version 1.0.1
                    
#r "nuget: Shane32.CsvLinq, 1.0.1"
                    
#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 Shane32.CsvLinq@1.0.1
                    
#: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=Shane32.CsvLinq&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Shane32.CsvLinq&version=1.0.1
                    
Install as a Cake Tool

Shane32.CsvLinq

NuGet Coverage Status

CsvLinq maps a single CSV file to a strongly typed list of row models. You define a context by deriving from CsvContext<TModel> and configuring the model once in OnModelCreating; the context then loads CSV data from a file or stream into List<TModel>, or saves a list back to a file or stream.

The library targets netstandard2.0 and has no runtime package dependencies.

Basic usage

public class InvoiceLine
{
    public DateTime Date { get; set; }
    public int Quantity { get; set; }
    public string Description { get; set; }
    public decimal Amount { get; set; }
    public string Notes { get; set; }
}

public class InvoiceLineCsv : CsvContext<InvoiceLine>
{
    protected override void OnModelCreating(CsvModelBuilder<InvoiceLine> builder)
    {
        builder.Column(x => x.Date);
        builder.Column(x => x.Quantity, "Qty");
        builder.Column(x => x.Description)
            .AlternateName("Desc");
        builder.Column(x => x.Amount);
        builder.Column(x => x.Notes)
            .Optional();

        builder.SkipEmptyRows();
    }
}

Read and write data directly:

var csv = new InvoiceLineCsv();

List<InvoiceLine> rows = csv.Load("invoice.csv");

rows.Add(new InvoiceLine {
    Date = DateTime.Today,
    Quantity = 2,
    Description = "Widgets",
    Amount = 12.50m
});

csv.Save("invoice-out.csv", rows);

Async file and stream APIs are also available:

var rows = await csv.LoadAsync("invoice.csv");
await csv.SaveAsync("invoice-out.csv", rows);

Configuration

CsvModelBuilder<TModel> and CsvColumnBuilder<TModel, TValue> are fluent builders. Configure your mappings inside OnModelCreating, then let CsvContext<TModel> handle load/save operations.

CsvModelBuilder<TModel> methods

Method Description
.LineEnding(string lineEnding) Sets the line ending used when writing CSV (\r\n, \n, etc.).
.LineEndingsInStrings(CsvLineEndingHandling handling) Controls how line endings inside field values are handled when writing.
.LineEndingReplacement(string replacement) Sets replacement text used when string line endings are replaced.
.EndsWithNewLine(bool endsWithNewLine) Controls whether output ends with a trailing line ending.
.OmitHeaderRow() Configures reading/writing CSV with no header row.
.SkipEmptyRows() Skips completely empty rows when loading CSV.
.Column<TValue>(Expression<Func<TModel, TValue>> memberAccessor) Maps a field/property using the member name as the column header.
.Column<TValue>(Expression<Func<TModel, TValue>> memberAccessor, string name) Maps a field/property using an explicit column header name.
.Format<TValue>(Func<string, TValue> deserialize, Func<TValue, string> serialize) Registers a type-wide formatter used by all mapped columns of that type.

CsvColumnBuilder<TModel, TValue> methods

Method Description
.AlternateName(string name) Adds an additional accepted header name (read-time alias).
.Optional() Marks the column as optional when loading.
.Required() Marks the column as required when loading.
.Nullable(bool nullable = true) For string columns, controls whether blank field values deserialize as null.
.Deserialize(Func<string, TValue> deserialize) Sets a column-specific deserializer.
.Serialize(Func<TValue, string> serialize) Sets a column-specific serializer.

Columns are required by default. Use .Optional() when a header may be missing or a field may be blank. Header matching is case-insensitive and trims surrounding whitespace, and alternate names can be defined for compatibility with older exports.

For string columns, blank fields deserialize according to the mapped member's nullable-reference annotation on supported target frameworks: string? receives null, while string receives string.Empty. When nullability metadata is not available, strings are treated as nullable. Use .Nullable() or .Nullable(false) to override the inferred behavior.

Default serializers/deserializers support these types and formats:

Type Default format Sample
string raw text Widgets
DateTime ISO 8601 date/time (no offset), read as DateTimeKind.Unspecified (any input offset is ignored) 2024-05-08T13:45:12.345
DateTimeOffset ISO 8601 round-trip with offset 2024-05-08T13:45:12.3450000-07:00
DateOnly (net6.0+) ISO 8601 date 2024-05-08
TimeOnly (net6.0+) ISO 8601 time 13:45:12.3450000
TimeSpan constant (c) 1.02:03:04.5000000
Guid dashed (D) f1dc7e7d-d63e-4279-8dfd-cecb6e26cda8
Uri URI string https://example.com/items/42
bool true/false, 1/0, Y/N, Yes/No True
enum enum name (case-insensitive on read) Pending
numeric primitives (int, decimal, etc.) invariant culture 45.99

Per-column serialization can be customized:

builder.Column(x => x.Quantity)
    .Deserialize(value => int.Parse(value.Substring(2)))
    .Serialize(value => "Q-" + value);

Type-wide formatters apply to every configured column of that type:

builder.Format<decimal>(
    value => decimal.Parse(value.TrimStart('$'), CultureInfo.InvariantCulture),
    value => "$" + value.ToString("0.00", CultureInfo.InvariantCulture));

CSV output options can be configured directly on the model builder:

builder.LineEnding("\r\n")
    .EndsWithNewLine(true)
    .LineEndingsInStrings(CsvLineEndingHandling.Replace)
    .LineEndingReplacement(" ");

Advanced customization

For advanced scenarios, CsvContext<TModel> exposes protected methods you can override:

Method Description
OnModelCreating(CsvModelBuilder<TModel> modelBuilder) Builds the model mapping (required override).
OnReadFile(TextReader reader) Customizes how an entire CSV document is read synchronously.
OnReadFileAsync(TextReader reader, CancellationToken cancellationToken = default) Customizes how an entire CSV document is read asynchronously.
OnReadRow(IReadOnlyList<string> fields, int rowNumber, CsvColumnModel[] columnMapping) Customizes conversion of one parsed record into a row model.
OnWriteFile(TextWriter writer, IEnumerable<TModel> data) Customizes how a full CSV document is written synchronously.
OnWriteFileAsync(TextWriter writer, IEnumerable<TModel> data, CancellationToken cancellationToken = default) Customizes how a full CSV document is written asynchronously.
OnWriteRow(TModel data) Customizes conversion of one row model into CSV field values.
DefaultDeserialize(string value, Type dataType) Overrides built-in type conversion for reading values.
DefaultSerialize(object value, Type dataType) Overrides built-in type conversion for writing values.

Most applications only need OnModelCreating; override the other methods when you need custom parsing/writing pipelines or conversion behavior.

Credits

Glory to Jehovah, Lord of Lords and King of Kings, creator of Heaven and Earth, who through his Son Jesus Christ, has reedemed me to become a child of God. -Shane32

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 is compatible.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.
  • net6.0

    • No dependencies.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 67 5/31/2026