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

.NET Core 3.1中如何将Redis Cache作为控制器特性使用?

在.NET Core 3.1中实现Redis缓存控制器特性

问题描述

我正在基于.NET Core 3.1开发项目,请问能否在控制器中把Redis缓存作为特性使用?以下是我的API示例代码:

[SampleAttribute]
[Route("/user/getrosetteRewardStatu")]
[Authorize(Roles = "SelectedPos", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ProducesResponseType(typeof(BaseResponse<GetRosetteInfoResponse>), 200)]
[Consumes("application/json")]
[Produces("application/json")]
[HttpGet]
public async Task<GetrosetteRewardStatuResponse> GetrosetteRewardStatu()
{
    return await mediator.Send(new GetrosetteRewardStatuRequest() { CustomerCode = HttpContext.User.Claims.ToCustomerCode() });
}

请问如何将示例中的[SampleAttribute]改造为Redis缓存特性?是否需要编写中间件?


回答

完全可以把Redis缓存做成控制器特性来用,不需要额外编写中间件,借助ASP.NET Core MVC自带的ActionFilterAttribute就能实现这类缓存逻辑。下面是具体实现步骤:

1. 配置Redis缓存服务

首先确保项目已引入Redis相关NuGet包:

Install-Package Microsoft.Extensions.Caching.StackExchangeRedis
Install-Package StackExchange.Redis

然后在Startup.cs的ConfigureServices方法中注册Redis缓存服务:

public void ConfigureServices(IServiceCollection services)
{
    // 其他服务注册...
    
    // 配置Redis缓存
    services.AddStackExchangeRedisCache(options =>
    {
        options.Configuration = "localhost:6379"; // 替换为你的Redis连接字符串
        options.InstanceName = "YourApiPrefix:"; // 缓存键前缀,避免不同项目缓存冲突
    });
}

2. 编写自定义Redis缓存特性

创建继承自ActionFilterAttribute的自定义特性,在请求执行前后处理缓存逻辑:

using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Distributed;
using System.Text.Json;

public class RedisCacheAttribute : ActionFilterAttribute
{
    private readonly int _expireMinutes;

    // 构造函数,允许指定缓存过期时间,默认5分钟
    public RedisCacheAttribute(int expireMinutes = 5)
    {
        _expireMinutes = expireMinutes;
    }

    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // 从DI容器获取分布式缓存服务
        var distributedCache = context.HttpContext.RequestServices.GetRequiredService<IDistributedCache>();
        
        // 生成唯一缓存键:结合请求路由+当前用户的CustomerCode,确保不同用户缓存独立
        var customerCode = context.HttpContext.User.Claims.ToCustomerCode();
        var routePath = context.HttpContext.Request.Path;
        var cacheKey = $"ApiCache:{routePath}:{customerCode}";

        // 尝试从Redis读取缓存
        var cachedData = await distributedCache.GetStringAsync(cacheKey);
        if (!string.IsNullOrEmpty(cachedData))
        {
            // 缓存存在:反序列化后直接返回,跳过原Action执行
            var cachedResponse = JsonSerializer.Deserialize<GetrosetteRewardStatuResponse>(cachedData);
            context.Result = new OkObjectResult(cachedResponse);
            return;
        }

        // 缓存不存在:执行原Action获取结果
        var executedContext = await next();
        
        // 如果Action执行成功,将结果存入Redis
        if (executedContext.Result is OkObjectResult okResult && okResult.Value is GetrosetteRewardStatuResponse response)
        {
            var serializedResponse = JsonSerializer.Serialize(response);
            await distributedCache.SetStringAsync(cacheKey, serializedResponse, new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(_expireMinutes)
            });
        }
    }
}

3. 在控制器中使用该特性

直接替换原有的[SampleAttribute]为自定义的Redis缓存特性即可,还可以指定过期时间:

[RedisCache(ExpireMinutes = 10)] // 替换SampleAttribute,设置缓存10分钟过期
[Route("/user/getrosetteRewardStatu")]
[Authorize(Roles = "SelectedPos", AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[ProducesResponseType(typeof(BaseResponse<GetRosetteInfoResponse>), 200)]
[Consumes("application/json")]
[Produces("application/json")]
[HttpGet]
public async Task<GetrosetteRewardStatuResponse> GetrosetteRewardStatu()
{
    return await mediator.Send(new GetrosetteRewardStatuRequest() { CustomerCode = HttpContext.User.Claims.ToCustomerCode() });
}

注意事项

  • 缓存键唯一性:如果接口有请求参数,需要把参数加入缓存键生成逻辑,避免不同参数请求共用缓存。
  • 序列化方式:示例用了System.Text.Json,若项目用Newtonsoft.Json,可替换为JsonConvert.SerializeObject和JsonConvert.DeserializeObject。
  • 缓存失效:业务数据更新时,需手动删除对应缓存键,保证数据一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 03:33:32