This package targets .NET Standard 2.0+ and .NET 5.0 or later.
RzR.Web.Middleware.ETag is ASP.NET Core middleware that adds HTTP validators to eligible responses and evaluates conditional request headers against the current response state.
It supports:
- automatic ETag generation from the response body
- request-specific
ETagandLast-Modifiedvalues through delegates - conditional request handling for
If-Match,If-None-Match, andIf-Modified-Since - DI-based replacement of the ETag generator through
IETagGenerator - endpoint-level opt-in, opt-out, and route-specific overrides on .NET 5+
Endpoint metadata features such as WithETag(), WithoutETag(), and ETagOptionsAttribute are available when your application consumes the .NET 5+ build of the package.
Install-Package RzR.Web.Middleware.ETagdotnet add package RzR.Web.Middleware.ETagPrefer configuring the middleware in DI with AddETag(...), then add UseETag() to the pipeline.
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using RzR.Web.Middleware.ETag;
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddRouting();
services.AddETag();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseETag();
app.UseEndpoints(endpoints =>
{
endpoints.MapGet("/etag", async context =>
{
context.Response.ContentType = "text/plain";
await context.Response.WriteAsync("payload");
});
});
}
}When you use explicit endpoint routing, place UseETag() after UseRouting() and before UseEndpoints(...) so endpoint metadata can be resolved correctly.
services.AddETag(options =>
{
options.MaxBodySize = 1024 * 1024;
options.ETagFactory = context => $"resource:{context.Request.Path}";
options.LastModifiedFactory = _ => DateTimeOffset.UtcNow;
});Default behavior:
- only
GETrequests are processed unless you extendSupportedMethods - only
200 OKresponses receive anETag - range requests, WebSocket requests, server-sent events, and oversized buffered bodies are skipped
- a matching
If-None-MatchonGETorHEADproduces304 Not Modified - a failing
If-Match, or a matchingIf-None-Matchon an unsafe method, produces412 Precondition Failed