Round #297
08 May 2026, 13:08· csharp· llama-3.3-70b-versatile· r13-clean-hints
- Complexity
- band 0
- ZP / UO / OBS
- 4 / 0 / 0
- Journey weight
- 284
- Lightshift ΔL
- +0.25
Prompt
Implement idempotency key middleware that deduplicates POST requests
Zero-point index (what the engine surfaced)
ZPI-ZPI-0002 | 2026-05-08T13:08:36Z
Implement idempotency key middleware that deduplicates POST requests
ZERO POINT — 4 entries (structural invariants)
● hsl(314.84, 100%, 32%) IMiddleware [contract]
● hsl(280.69, 100%, 32%) RequestDelegate [contract]
● hsl(329.61, 100%, 21%) IDistributedCache [contract]
● hsl(136.10, 100%, 31%) DbContext [contract]
UNOBSERVED — 0 entries (implied truths)
OBSERVED — 0 entries (explicit in request)
COMPLEXITY │ 4 entries │ spread: 0° │ band: LOW
Baseline response (no ZPI)
Idempotency Key Middleware
========================
### Overview
The idempotency key middleware is designed to prevent duplicate POST requests from being processed by an API. This is achieved by storing the idempotency key of each request in a cache, and checking if the key already exists before processing the request.
### Implementation
Here is a simple implementation of idempotency key middleware in C#:
```csharp
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Threading.Tasks;
public class IdempotencyKeyMiddleware
{
private readonly RequestDelegate _next;
private readonly IMemoryCache _cache;
public IdempotencyKeyMiddleware(RequestDelegate next, IMemoryCache cache)
{
_next = next;
_cache = cache;
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Method == "POST")
{
var idempotencyKey = context.Request.Headers["Idempotency-Key"].ToString();
if (string.IsNullOrEmpty(idempotencyKey))
{
context.Response.StatusCode = 400;
await context.Response.WriteAsync("Idempotency key is required");
return;
}
if (_cache.TryGetValue(idempotencyKey, out _))
{
context.Response.StatusCode = 409;
await context.Response.WriteAsync("Request has already been processed");
return;
}
try
{
await _next(context);
_cache.Set(idempotencyKey, true, TimeSpan.FromHours(1));
}
catch (Exception ex)
{
// Log the exception
Console.WriteLine(ex.Message);
throw;
}
}
else
{
await _next(context);
}
}
}
```
### Usage
To use this middleware, you need to add it to the pipeline in the `Startup.cs` file:
```csharp
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
// ...
app.UseMiddleware<IdempotencyKeyMiddleware>();
// ...
}
```
You also need to add the `IMemoryCache` service to the DI container in the `Startup.cs` file:
```csharp
public void ConfigureServices(IServiceCollection services)
{
services.AddMemoryCache();
// ...
}
```
### Example Use Case
Here is an example of how to use the idempotency key middleware with a simple API controller:
```csharp
[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
[HttpPost]
public IActionResult MyAction([FromBody] MyModel model)
{
// Process the request
return Ok();
}
}
```
When sending a POST request to the `MyAction` method, you need to include the idempotency key in the `Idempotency-Key` header:
```bash
curl -X POST \
http://localhost:5000/api/MyController \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: my-idempotency-key' \
-d '{"name":"John","age":30}'
```
If you send the same request again with the same idempotency key, the middleware will return a 409 status code indicating that the request has already been processed.
Enhanced response (with ZPI)
```csharp
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Threading.Tasks;
public class IdempotencyKeyMiddleware
{
private readonly RequestDelegate _next;
private readonly IDistributedCache _cache;
public IdempotencyKeyMiddleware(RequestDelegate next, IDistributedCache cache)
{
_next = next;
_cache = cache;
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Method == "POST")
{
var idempotencyKey = context.Request.Headers["Idempotency-Key"].ToString();
if (!string.IsNullOrEmpty(idempotencyKey))
{
var cacheKey = $"idempotency:{idempotencyKey}";
var cachedResponse = await _cache.GetStringAsync(cacheKey);
if (cachedResponse != null)
{
await context.Response.WriteAsync(cachedResponse);
return;
}
using var responseStream = new System.IO.MemoryStream();
var originalResponseBody = context.Response.Body;
context.Response.Body = responseStream;
await _next(context);
context.Response.Body = originalResponseBody;
var responseBody = await new string(responseStream.ToArray());
await _cache.SetStringAsync(cacheKey, responseBody, new DistributedCacheEntryOptions
{
AbsoluteExpirationRelativeToNow = TimeSpan.FromHours(1)
});
await context.Response.WriteAsync(responseBody);
}
else
{
await _next(context);
}
}
else
{
await _next(context);
}
}
}
public static class IdempotencyKeyMiddlewareExtensions
{
public static IApplicationBuilder UseIdempotencyKeyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<IdempotencyKeyMiddleware>();
}
}
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDistributedMemoryCache();
services.AddControllers();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseIdempotencyKeyMiddleware();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
```
This implementation provides idempotency key middleware that deduplicates POST requests. Here's how it works:
1. The middleware checks if the incoming request is a POST request. If it's not, the request is passed to the next middleware in the pipeline.
2. If the request is a POST, the middleware checks for the presence of an "Idempotency-Key" header. If the header is missing, the request is passed to the next middleware.
3. If the "Idempotency-Key" header is present, the middleware checks the distributed cache for a cached response associated with the provided idempotency key. If a cached response is found, it's returned immediately.
4. If no cached response is found, the middleware proceeds with the request, caching the response body in the distributed cache using the provided idempotency key.
5. The cached response is stored for a limited time (in this case, one hour) to prevent the cache from growing indefinitely.
To use this middleware, you need to add the `UseIdempotencyKeyMiddleware` method to the `Configure` method in the `Startup` class. Additionally, you need to configure the distributed cache in the `ConfigureServices` method.
**Example Use Case:**
Suppose you have a controller with a POST action that creates a new resource:
```csharp
[ApiController]
[Route("api/[controller]")]
public class MyController : ControllerBase
{
[HttpPost]
public async Task<IActionResult> CreateResource([FromBody] MyModel model)
{
// Create a new resource
var resourceId = await CreateResourceAsync(model);
return CreatedAtAction(nameof(CreateResource), new { id = resourceId }, resourceId);
}
private async Task<int> CreateResourceAsync(MyModel model)
{
// Simulate resource creation
await Task.Delay(100);
return 1;
}
}
```
To make this action idempotent, you can include an "Idempotency-Key" header in the request:
```http
POST /api/MyController HTTP/1.1
Idempotency-Key: my-idempotency-key
Content-Type: application/json
{
"name": "My Resource"
}
```
If you send the same request multiple times with the same "Idempotency-Key" header, the middleware will return the cached response instead of creating a new resource.
Grader chain
Each grader reads the same baseline + enhanced pair and casts an independent verdict. Disagreement is the framework's own signal — not noise to be averaged away.
V1claude-sonnet-4-6
WorseV4qwen2.5-coder-7b-instruct
BetterComments
Our grader said what it said. What do you say? Comment as a guest below.
No comments yet. Be the first to say what you make of this round.