DKNet.AspCore.Idempotency.MsSqlStore
10.1.16
See the version list below for details.
dotnet add package DKNet.AspCore.Idempotency.MsSqlStore --version 10.1.16
NuGet\Install-Package DKNet.AspCore.Idempotency.MsSqlStore -Version 10.1.16
<PackageReference Include="DKNet.AspCore.Idempotency.MsSqlStore" Version="10.1.16" />
<PackageVersion Include="DKNet.AspCore.Idempotency.MsSqlStore" Version="10.1.16" />
<PackageReference Include="DKNet.AspCore.Idempotency.MsSqlStore" />
paket add DKNet.AspCore.Idempotency.MsSqlStore --version 10.1.16
#r "nuget: DKNet.AspCore.Idempotency.MsSqlStore, 10.1.16"
#:package DKNet.AspCore.Idempotency.MsSqlStore@10.1.16
#addin nuget:?package=DKNet.AspCore.Idempotency.MsSqlStore&version=10.1.16
#tool nuget:?package=DKNet.AspCore.Idempotency.MsSqlStore&version=10.1.16
DKNet.AspCore.Idempotency.MsSqlStore
A SQL Server-backed persistent store for DKNet.AspCore.Idempotency — idempotency keys and cached
responses survive application restarts, with a race-free reserve-then-check flow under concurrent
duplicate requests.
Features
- Persists idempotency keys and cached responses in SQL Server via EF Core
- Race-free duplicate handling backed by a database unique index, not application-level locking
- Migrations ship with the package and run automatically on first use
- Configured through the same
IdempotencyOptionsthe core package already exposes — no extra options type to learn
Installation
dotnet add package DKNet.AspCore.Idempotency.MsSqlStore
Quick Start
using DKNet.AspCore.Idempotency;
using DKNet.AspCore.Idempotency.MsSqlStore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddIdempotencyWithMsSqlStore(
builder.Configuration.GetConnectionString("IdempotencyDb")!,
options =>
{
options.Expiration = TimeSpan.FromHours(48);
options.ConflictHandling = IdempotentConflictHandling.CachedResult;
});
var app = builder.Build();
app.MapPost("/orders", () => Results.Ok())
.RequiredIdempotentKey();
app.Run();
Customisation reference
There is no SQL Server-specific options type. AddIdempotencyWithMsSqlStore configures the shared IdempotencyOptions from
DKNet.AspCore.Idempotency:
| Knob | Type | Default | Effect |
|---|---|---|---|
IdempotencyHeaderKey |
string |
"X-Idempotency-Key" |
Request header the filter reads the key from. |
IdempotencyKeyPattern |
string |
^[a-zA-Z0-9\-_]+$ |
Regex a key must match; a mismatch is 400 Bad Request. |
MaxIdempotencyKeyLength |
int |
255 |
Longer keys are rejected with 400. |
ConflictHandling |
IdempotentConflictHandling |
ConflictResponse |
ConflictResponse answers a duplicate with 409; CachedResult replays the original status, body and content type. |
Expiration |
TimeSpan |
4 hours |
Absolute lifetime of a cached result before the key is treated as new again. |
InFlightReservationTimeout |
TimeSpan |
30 seconds |
Lifetime of the in-flight reservation placeholder before it can be reclaimed. |
MinStatusCodeForCaching |
int |
200 |
Inclusive lower bound of the cacheable status range (must be ≥ 100). |
MaxStatusCodeForCaching |
int |
299 |
Inclusive upper bound (must be ≤ 599 and ≥ the minimum). |
AdditionalCacheableStatusCodes |
HashSet<int> (get-only, mutable) |
empty | Extra status codes cached outside the min/max window. |
CachePrefix |
string |
"idem" |
Prepended, unchanged, to every storage key. |
JsonSerializerOptions |
JsonSerializerOptions |
camelCase naming policy | Used to serialize and deserialize the cached response body. |
KeyScopeResolver |
Func<HttpContext, string?>? |
null |
Custom caller-scope resolver. When set it is used verbatim and the default chain is skipped. |
ScopeHmacSecret |
string? |
null |
Enables the Authorization-header HMAC-SHA256 fallback in the default scope chain. |
IncludeClientIpInScope |
bool |
false |
Enables the client-IP fallback in the default scope chain. |
Values are validated eagerly at registration: an empty header key or cache prefix, a non-positive expiration, a
status-code window outside 100–599 or with min above max, a null JsonSerializerOptions, a
MaxIdempotencyKeyLength below 1, an empty key pattern, or a whitespace ScopeHmacSecret each throw
ArgumentException immediately rather than failing at request time.
Registration entry points
| Method | Registers |
|---|---|
AddIdempotencyMsSqlStore(connectionString) |
IdempotencyDbContext and IDbContextFactory<IdempotencyDbContext> only — not the key store, so on its own it leaves no IIdempotencyKeyStore registered. |
AddIdempotencyWithMsSqlStore(connectionString, config) |
The above, then AddIdempotentKey<IdempotencySqlServerStore>(config). This is the call an application makes. |
Fixed by this package, not exposed as options
| Setting | Value |
|---|---|
EnableRetryOnFailure |
3 retries, 5 seconds apart |
UseQuerySplittingBehavior |
QuerySplittingBehavior.SplitQuery |
MigrationsAssembly |
this package's assembly |
MigrationsHistoryTable |
[migrate].[IdempotencyDbContext] |
optionsLifetime |
ServiceLifetime.Singleton (the DbContext itself stays scoped) |
| Table, indexes, constraint | IdempotencyKeys with UX_CompositeKey (unique), IX_IdempotencyKeys_ExpiresAt, and CK_StatusCode_Valid (100–599) |
You provide a reachable database and a login that can create tables in it; the package creates and migrates the
table on first use. Nothing sweeps expired rows — ExpiresAt is indexed so you can add your own cleanup job.
IdempotencySqlServerStore is internal, so AddIdempotentKey<IdempotencySqlServerStore>() does not compile in
application code — AddIdempotencyWithMsSqlStore(...) is the supported way in. Both methods are first-wins: a
second call with a different connection string is silently a no-op.
Learn more
Full registration details, the SQL Server schema, and gotchas around migrations and concurrency: DKNet.AspCore.Idempotency.MsSqlStore docs.
Requirements
- .NET 10.0+
- SQL Server 2019+ (or Azure SQL Database)
License
MIT — see LICENSE.
About
Developed by Steven Hoang.
| Product | Versions 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. |
-
net10.0
- DKNet.AspCore.Idempotency (>= 10.1.16)
- DKNet.AspCore.Idempotency.Relational (>= 10.1.16)
- Microsoft.EntityFrameworkCore (>= 10.0.11)
- Microsoft.EntityFrameworkCore.SqlServer (>= 10.0.11)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.11)
- Microsoft.Extensions.Options (>= 10.0.11)
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 |
|---|---|---|
| 10.1.19 | 36 | 9/3/2026 |
| 10.1.18 | 37 | 9/3/2026 |
| 10.1.17 | 43 | 9/3/2026 |
| 10.1.16 | 37 | 9/3/2026 |
| 10.1.15 | 77 | 9/1/2026 |
| 10.1.14 | 66 | 9/1/2026 |
| 10.1.13 | 80 | 8/31/2026 |
| 10.1.12 | 83 | 8/25/2026 |
| 10.1.11 | 89 | 8/24/2026 |
| 10.1.10 | 85 | 8/22/2026 |
| 10.1.9 | 104 | 8/22/2026 |
| 10.1.8 | 89 | 8/21/2026 |
| 10.1.7 | 100 | 8/21/2026 |
| 10.1.6 | 91 | 8/21/2026 |
| 10.1.5 | 89 | 8/20/2026 |
| 10.1.4 | 86 | 8/20/2026 |
| 10.1.3 | 105 | 8/19/2026 |
| 10.1.2 | 84 | 8/19/2026 |
| 10.1.1 | 88 | 8/19/2026 |
| 10.0.36 | 99 | 8/18/2026 |