.NET Core 7中POST/更新操作后刷新Output Cache的实现方法
.NET Core 7 Output Cache 增改记录时的缓存刷新方案
针对你基于基础策略配置的Output Cache,在新增/更新记录时可以通过以下几种实用方案实现缓存失效:
1. 标签式缓存失效(推荐)
这是最灵活且高效的方案,通过给缓存条目打标签,增改操作时移除对应标签的所有缓存。
步骤1:给基础策略或接口添加缓存标签
修改你的Output Cache配置,给所有走基础策略的缓存统一打标签:
services.AddCors(); services.AddOutputCache(opt => { opt.AddBasePolicy(builder => { builder.Expire(TimeSpan.FromMinutes(10)) // 保留原有过期配置 .Tag("data-records"); // 给基础策略缓存打统一标签 }); });
如果需要更细粒度控制,也可以在单个Action上单独指定标签:
[HttpGet] [OutputCache(Tags = new[] { "product-records" })] public async Task<IActionResult> GetProducts() { // 业务逻辑实现 }
步骤2:在增/改接口中移除对应标签的缓存
注入IOutputCacheStore服务,调用EvictByTagAsync方法清除对应标签的缓存:
using Microsoft.AspNetCore.OutputCaching; [ApiController] [Route("api/[controller]")] public class RecordsController : ControllerBase { private readonly YourDbContext _dbContext; private readonly IOutputCacheStore _cacheStore; public RecordsController(YourDbContext dbContext, IOutputCacheStore cacheStore) { _dbContext = dbContext; _cacheStore = cacheStore; } [HttpPost] public async Task<IActionResult> CreateRecord(RecordDto dto) { // 执行新增逻辑 _dbContext.Records.Add(new Record { /* 字段赋值 */ }); await _dbContext.SaveChangesAsync(); // 清除所有带"data-records"标签的缓存 await _cacheStore.EvictByTagAsync("data-records", CancellationToken.None); return Ok(); } [HttpPut("{id}")] public async Task<IActionResult> UpdateRecord(int id, RecordDto dto) { var record = await _dbContext.Records.FindAsync(id); if (record == null) return NotFound(); // 执行更新逻辑 record.Name = dto.Name; // ...其他字段更新操作 await _dbContext.SaveChangesAsync(); // 清除对应标签的缓存 await _cacheStore.EvictByTagAsync("data-records", CancellationToken.None); return Ok(); } }
2. 单个缓存条目失效
如果只需要失效某一条记录的详情缓存,可以通过生成对应缓存键精准移除:
using Microsoft.AspNetCore.OutputCaching; [HttpPut("{id}")] public async Task<IActionResult> UpdateRecord(int id, RecordDto dto, IOutputCacheKeyProvider keyProvider) { // 执行更新逻辑... // 生成对应GET详情接口的缓存键 var cacheKey = await keyProvider.CreateAsync(new OutputCacheContext { HttpContext = HttpContext, RouteValues = new RouteValueDictionary { { "id", id } }, RequestPath = $"/api/records/{id}", RequestMethod = "GET" }, CancellationToken.None); // 移除单个缓存条目 await _cacheStore.EvictAsync(cacheKey, CancellationToken.None); return Ok(); }
3. 前缀式批量失效
如果你的缓存有统一前缀,可以通过前缀批量清除相关缓存:
步骤1:配置基础策略时添加前缀
services.AddOutputCache(opt => { opt.AddBasePolicy(builder => { builder.Expire(TimeSpan.FromMinutes(10)) .WithPrefix("api-records"); }); });
步骤2:增改时移除前缀对应的缓存
await _cacheStore.EvictByPrefixAsync("api-records", CancellationToken.None);
注意事项
IOutputCacheStore是Output Cache的核心服务,无需额外配置,直接注入即可使用。- 若使用分布式缓存(如Redis),以上方法完全兼容,底层会自动适配分布式存储实现。
- 标签和前缀的粒度可根据业务调整,避免过度失效影响系统性能。
内容的提问来源于stack exchange,提问作者Michael Marmah
相关产品推荐
相关产品推荐

