IdempotencyGuard.AspNetCore
1.3.0
dotnet add package IdempotencyGuard.AspNetCore --version 1.3.0
NuGet\Install-Package IdempotencyGuard.AspNetCore -Version 1.3.0
<PackageReference Include="IdempotencyGuard.AspNetCore" Version="1.3.0" />
<PackageVersion Include="IdempotencyGuard.AspNetCore" Version="1.3.0" />
<PackageReference Include="IdempotencyGuard.AspNetCore" />
paket add IdempotencyGuard.AspNetCore --version 1.3.0
#r "nuget: IdempotencyGuard.AspNetCore, 1.3.0"
#:package IdempotencyGuard.AspNetCore@1.3.0
#addin nuget:?package=IdempotencyGuard.AspNetCore&version=1.3.0
#tool nuget:?package=IdempotencyGuard.AspNetCore&version=1.3.0
IdempotencyGuard.AspNetCore
ASP.NET Core middleware for automatic idempotent request handling. Part of the IdempotencyGuard library.
Processes Idempotency-Key headers, fingerprints requests, caches responses, and replays them on duplicate requests — preventing double processing from client retries, network failures, and timeout scenarios.
Installation
dotnet add package IdempotencyGuard.AspNetCore
# Choose a store for production
dotnet add package IdempotencyGuard.Redis # Recommended
dotnet add package IdempotencyGuard.PostgreSql
dotnet add package IdempotencyGuard.SqlServer
Quick Start
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddIdempotencyGuard(options =>
{
options.HeaderName = "Idempotency-Key";
options.ClaimTtl = TimeSpan.FromMinutes(5);
options.ResponseTtl = TimeSpan.FromHours(24);
options.MissingKeyPolicy = MissingKeyPolicy.Reject;
});
builder.Services.AddIdempotencyGuardInMemoryStore(); // Use Redis/SQL in production
var app = builder.Build();
app.UseIdempotencyGuard();
How It Works
Request with Idempotency-Key header
|
+-- New key --> Claim --> Execute --> Cache response
+-- Completed key --> Replay cached response
+-- In-progress key --> Wait or return 409
+-- Different body --> Return 422 (fingerprint mismatch)
+-- Processing fail --> Release claim for retry
Per-Endpoint Configuration
Use RequireIdempotency() for minimal APIs:
app.MapPost("/payments", (PaymentRequest request) =>
{
// Per-endpoint TTL overrides
}).RequireIdempotency(options =>
{
options.ClaimTtlSeconds = 120;
options.ResponseTtlSeconds = 86400;
});
Or use the [Idempotent] attribute for controller-based APIs:
[Idempotent(ClaimTtlSeconds = 120, ResponseTtlSeconds = 86400)]
public IActionResult CreatePayment(PaymentRequest request) { ... }
Selective Fingerprinting
Specify which properties define request identity, so non-business fields (timestamps, correlation IDs) don't cause fingerprint mismatches:
app.MapPost("/payments", (PaymentRequest request) =>
{
// Only specified fields are fingerprinted
}).RequireIdempotency(options =>
{
options.FingerprintProperties = [nameof(PaymentRequest.Amount), nameof(PaymentRequest.Currency)];
options.FingerprintQueryParameters = ["version"];
options.FingerprintRouteValues = ["merchantId"];
});
Key Features
- Claim-then-process pattern with configurable TTLs
- SHA256 fingerprinting with JSON normalisation to detect payload mismatches
- Selective fingerprinting via
nameof()for body properties, query parameters, and route values - Concurrent request handling — wait-then-replay or return 409
- Custom error responses via
ErrorResponseFactory(RFC 7807 compatible) - Response header filtering with allow/deny lists
- Key prefixing for multi-tenant or multi-environment setups
- Downstream key generation for propagating idempotency to external services
- Built-in metrics via OpenTelemetry (
IdempotencyGuardmeter) - Expired entry cleanup via background service with configurable batch size
Documentation
See the full documentation on GitHub for complete configuration reference, store setup guides, and production examples.
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 is compatible. 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 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
- IdempotencyGuard (>= 1.3.0)
-
net8.0
- IdempotencyGuard (>= 1.3.0)
-
net9.0
- IdempotencyGuard (>= 1.3.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.