You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Minimal API如何实现指定端点的客户端响应缓存并封装扩展方法?

在ASP.NET Core Minimal API中封装客户端响应缓存扩展方法

从传统Controller迁移到Minimal API后,我们需要实现类似[ResponseCache]特性的端点级客户端响应缓存——官方全局缓存中间件无法满足单个端点定制策略的需求,手动设置响应头可行但不够优雅,下面是封装成UseResponseCache扩展方法的实现方案:

基础版扩展方法(仅支持max-age)

先实现最基础的版本,支持设置缓存有效期:

public static class ResponseCacheExtensions
{
    public static RouteHandlerBuilder UseResponseCache(this RouteHandlerBuilder builder, int durationSeconds)
    {
        return builder.Use(async (context, next) =>
        {
            await next();
            
            // 仅对成功响应添加缓存头
            if (context.Response.StatusCode is >= 200 and < 300)
            {
                context.Response.Headers.CacheControl = $"public, max-age={durationSeconds}";
            }
        });
    }
}

增强版扩展方法(支持多参数)

如果需要模拟[ResponseCache]的更多特性(比如VaryByHeader、NoStore),可以扩展参数:

public static class ResponseCacheExtensions
{
    public static RouteHandlerBuilder UseResponseCache(
        this RouteHandlerBuilder builder, 
        int durationSeconds, 
        string? varyByHeader = null, 
        bool noStore = false)
    {
        return builder.Use(async (context, next) =>
        {
            await next();
            
            if (context.Response.StatusCode is >= 200 and < 300)
            {
                var cacheControlSegments = new List<string>();
                
                if (noStore)
                {
                    cacheControlSegments.Add("no-store");
                }
                else
                {
                    cacheControlSegments.Add($"public, max-age={durationSeconds}");
                }
                
                context.Response.Headers.CacheControl = string.Join(", ", cacheControlSegments);
                
                if (!string.IsNullOrWhiteSpace(varyByHeader))
                {
                    context.Response.Headers.Vary = varyByHeader;
                }
            }
        });
    }
}

使用示例

基础缓存配置

app.MapGet("/data", () =>
{
    return new { message = "Cached Data" };
}).UseResponseCache(60); // 缓存60秒

带User-Agent差异化的缓存

app.MapGet("/user-specific-content", () =>
{
    return new { message = "User-Agent Cached Content" };
}).UseResponseCache(30, varyByHeader: "User-Agent"); // 按User-Agent区分缓存,有效期30秒

禁用缓存(NoStore)

app.MapGet("/sensitive-data", () =>
{
    return new { message = "Sensitive Data" };
}).UseResponseCache(0, noStore: true); // 禁止客户端缓存

核心逻辑说明

  • 扩展方法基于RouteHandlerBuilder,通过Use方法给单个端点添加专属中间件,不会影响全局其他端点。
  • 中间件在后续流程执行完成后(即端点生成响应后),检查响应状态码,仅对成功响应添加缓存头,避免缓存错误结果。
  • 完全模拟[ResponseCache]特性的核心行为,同时保留Minimal API的简洁风格。

内容的提问来源于stack exchange,提问作者rst

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:47:23