Atulin.Sqids.AspNetCore 1.0.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package Atulin.Sqids.AspNetCore --version 1.0.0
                    
NuGet\Install-Package Atulin.Sqids.AspNetCore -Version 1.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="Atulin.Sqids.AspNetCore" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Atulin.Sqids.AspNetCore" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="Atulin.Sqids.AspNetCore" />
                    
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 Atulin.Sqids.AspNetCore --version 1.0.0
                    
#r "nuget: Atulin.Sqids.AspNetCore, 1.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 Atulin.Sqids.AspNetCore@1.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=Atulin.Sqids.AspNetCore&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=Atulin.Sqids.AspNetCore&version=1.0.0
                    
Install as a Cake Tool

Sqids.AspNetCore

Coverage Status Tests & Coverage

A strongly-typed Sqid for ASP.NET Core, built on the Sqids ID generation scheme. It encodes non-negative integers into short, URL-safe, non-sequential IDs and decodes them back.

This library provides first-class integration with ASP.NET Core: route/query/form/model binding for Minimal APIs, MVC, and Razor Pages; JSON serialization/deserialization via a built-in JsonConverter; and OpenAPI schema generation. IDs are validated to be in canonical form, matching the behavior of other official Sqids implementations.

Differences from Sqids.NET

This library is not a fork of the core Sqids library; it builds a higher-level Sqid type and ASP.NET Core integration on top of the same spec. Key differences:

Aspect Sqids.AspNetCore sqids-dotnet (core)
Primary focus ASP.NET Core integration (binding, JSON, OpenAPI, route constraints) Generic, framework-agnostic Sqids encoder/decoder
Type model Strongly-typed Sqid readonly struct (value type) wrapping a single long value SqidsEncoder<T> / SqidsEncoder for encoding/decoding numeric sequences
API surface Focused on binding/parsing as a single ID value (Parse, TryParse, From, Value) Focused on encoding/decoding numbers (Encode, Decode) with support for multiple numbers
Integration Automatic model binding, TypeConverter, {id:sqid} route constraint, JsonConverter, OpenAPI schema (AddSqidSchema) No ASP.NET Core-specific binding/JSON/OpenAPI helpers
Numeric types Single integer (long) for the Sqid value Generic math / overloads for many integral types (int, long, ulong, etc.) and multiple numbers
Canonicality enforcement Always validates canonical form on parse (re-encodes and compares); explicit parse errors Canonicality is a user concern in general use (you must re-encode and compare if needed)
Usage pattern Treat Sqid as a first-class domain type in web models/controllers Treat encoder as a service to transform numbers<->strings

If you only need core encoding/decoding (not ASP.NET Core binding/JSON/OpenAPI), use sqids-dotnet. If you're building an ASP.NET Core app and want a Sqid value type that "just works" with model binding, JSON, and OpenAPI, this library is a better fit.

References

Installation

Add the package to your project:

dotnet add package Sqids.AspNetCore

Quick Start

Register Sqids and (optionally) OpenAPI support in Program.cs:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSqids(options =>
{
    options.MinLength = 8; // pad IDs to at least this length
    // options.Alphabet = "abcdefghijklmnopqrstuvwxyz0123456789";
    // options.Blocklist.Add("badword");
});

builder.Services.AddOpenApi(o => o.AddSqidSchema());

var app = builder.Build();

app.MapOpenApi();
app.Run();

AddSqids() must be called before the first Sqid is used (the library uses a process-wide default codec). Calling it again after first use throws.

Usage

The Sqid type

Sqid is a readonly struct wrapping a non-negative long. It supports equality, ordering (numeric), parsing, and formatting. Parsing accepts only the canonical form produced by encoding the same value with the same alphabet, MinLength, and blocklist rules.

// Create from a number
Sqid id = Sqid.From(42);
Console.WriteLine(id.ToString()); // e.g. "Lk"

// Parse
Sqid parsed = Sqid.Parse("Lk");
bool ok = Sqid.TryParse("Lk", out var value);

// Span/UTF-8 overloads are also supported
Sqid.Parse("Lk".AsSpan());
Sqid.TryParse("Lk"u8, out _);

Dependency Injection: ISqidCodec

For programmatic encoding/decoding with custom options or to control the codec instance, inject ISqidCodec:

app.MapGet("/encode/{n:long}", (long n, ISqidCodec codec) => codec.Encode(n));
app.MapGet("/decode/{id}", (string id, ISqidCodec codec) =>
    codec.TryDecode(id, out var v) ? Results.Ok(v) : Results.BadRequest("Invalid id"));

Minimal APIs

Sqid binds directly from route, query, or body parameters:

// Route binding
app.MapGet("/users/{id:sqid}", (Sqid id) => $"User {id.Value}");

// Query binding
app.MapGet("/users", (Sqid? id) => id is null ? "All" : $"User {id.Value}");

// JSON body binding (works automatically via the built-in JsonConverter)
app.MapPost("/users", (UserDto user) => Results.Ok(user));

MVC Controllers & Razor Pages

Sqid works as an action parameter, model property, or route constraint. The included model binder, TypeConverter, and {id:sqid} route constraint are registered automatically when you call AddSqids().

public class User
{
    public Sqid Id { get; set; }
    public string Name { get; set; } = string.Empty;
}

public class UsersController : Controller
{
    [HttpGet("{id:sqid}")]
    public IActionResult Get(Sqid id) => Ok(id);
}

JSON Serialization

Sqid is serialized as a string and deserialized from a string only. Dictionary keys are also supported. Numbers are rejected during deserialization.

var user = new User { Id = Sqid.From(123), Name = "Alice" };
string json = JsonSerializer.Serialize(user); // {"Id":"Uk","Name":"Alice"}
var restored = JsonSerializer.Deserialize<User>(json)!;

OpenAPI

Call AddSqidSchema() when configuring OpenAPI to add a reusable Sqid component schema with proper constraints (type: string, format: sqid, pattern: ^[0-9A-Za-z]+$, minLength: 2, maxLength: 12, description, and example). All Sqid and Sqid? properties in your models will reference the shared component.

builder.Services.AddOpenApi(o => o.AddSqidSchema());

// Then document endpoints as normal
app.MapGet("/openapi/v1.json", () => ...);

Configuration

SqidOptions lets you customize the codec:

Option Default Description
Alphabet Full alphanumeric set (0-9A-Za-z) The character set used to encode/decode. Must contain 3–94 distinct visible ASCII characters.
MinLength 0 If greater than 0, IDs are padded to at least this length (with padding chars chosen per the spec).
Blocklist Official Sqids blocklist A list of words/strings to avoid appearing in generated IDs (checked at start, end, and anywhere). The implementation only checks words the current alphabet can actually spell.
builder.Services.AddSqids(o => {
    o.MinLength = 10;
    o.Alphabet = "abcdef0123456789";
    o.Blocklist = new HashSet<string> { "abc", "def" };
});

Notes on Canonicality & Safety

  • Canonical form required: Parsing/accepting an ID re-encodes its decoded value and requires the result to match exactly. This rejects non-canonical forms such as leading-zero-like artifacts, wrong padding, IDs produced with different options, blocked IDs, or IDs that do not represent a single value.
  • Single-value only: The library encodes and decodes a single integer per ID (matching the Sqids design). Multi-number encodings are rejected on parse with a distinct parse error.
  • Not encryption or obfuscation of sensitive data: Sqids are intended for public, non-sensitive identifiers. Do not rely on them for security.
  • Blocklist aware: When a generated ID would contain a blocked word, the encoder retries with a different permutation until it finds a safe ID or exhausts attempts.

Building & Testing

This project targets net10.0. Tests use TUnit on Microsoft.Testing.Platform.

# Build everything
dotnet build

# Run tests
dotnet test

License

MIT License

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

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.1.0 83 10/18/2026
1.0.0 85 10/17/2026