网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
#nullable enable
using System.Collections;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;

namespace Dpz.Core.WebApi.Middleware;

/// <summary>
/// 缓存
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class CacheAttribute: ActionFilterAttribute
{
    private const string CurrentRequestCacheKey = "Dpz.Core.WebApi:CacheKey";
    
    
    /// <summary>
    /// Action 执行
    /// </summary>
    /// <param name="context"></param>
    /// <param name="next"></param>
    public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        var key = GeneratorCacheKey(context);
        if (string.IsNullOrEmpty(key))
            return;
        context.HttpContext.Items[CurrentRequestCacheKey] = key;
        //context.HttpContext.
        
        var serviceProvider = context.HttpContext.RequestServices;
        // var cacheClient = serviceProvider.GetService<ICacheClient>();
        //cacheClient.get
            
            
        Console.WriteLine("OnActionExecutionAsync");
        await base.OnActionExecutionAsync(context,next);
    }

    /// <summary>
    /// Result 执行
    /// </summary>
    /// <param name="context"></param>
    /// <param name="next"></param>
    public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
    {
        
        Console.WriteLine("OnResultExecutionAsync");
        await base.OnResultExecutionAsync(context,next);
    }

    private string? GeneratorCacheKey(ActionExecutingContext context)
    {
        if (context.Controller is not Controller controller)
            return null;
        var actionDescriptor = context.ActionDescriptor as ControllerActionDescriptor;
        var action = actionDescriptor?.ActionName;
        
        
        var actionParameters = context
            .ActionArguments
            .Where(x => x.Value != null)
            .Select(x => x.Key + "=" + GetValue(x.Value!));
        var parameters = string.Join("&", actionParameters);
        var type = controller.GetType();
        return $"{type.Namespace}:{type.Name}:{action}:{parameters}";
    }
    
    private string GetValue(object value)
    {
        if (value is IEnumerable paramArray and not string)
        {
            var concatValue = string.Empty;

            return paramArray.Cast<object>()
                .Aggregate(concatValue, (current, paramValue) => current + (paramValue + ";"));
        }

        return value.ToString()!;
    }
}
⚠⚠    以下内容为AI分析的结果,请根据实际情况进行判断。

这段代码定义了一个名为 CacheAttribute 的 ASP.NET Core 中间件特性(Attribute),用于在 Web API 中实现缓存功能。下面是对代码的详细解释:

1. 特性定义

  • CacheAttribute 继承自 ActionFilterAttribute,这意味着它可以在控制器的操作方法执行前后进行处理。
  • 特性可以应用于方法或类(AttributeTargets.Method | AttributeTargets.Class)。

2. 常量定义

  • CurrentRequestCacheKey 是一个字符串常量,用于在 HTTP 上下文中存储当前请求的缓存键。

3. OnActionExecutionAsync 方法

  • 该方法在控制器操作方法执行之前被调用。
  • 它生成一个缓存键(key),如果键为空,则直接返回。
  • 将生成的缓存键存储在 HttpContext.Items 中,以便在后续处理中使用。
  • 代码中有注释部分,表明可以从服务提供者中获取缓存客户端(ICacheClient),并在此处实现缓存的获取逻辑。
  • 最后,调用 base.OnActionExecutionAsync(context, next) 继续执行后续的操作。

4. OnResultExecutionAsync 方法

  • 该方法在控制器操作方法执行后被调用。
  • 目前只打印了一条消息,表示该方法被调用。可以在这里实现将结果缓存的逻辑。

5. GeneratorCacheKey 方法

  • 该方法用于生成缓存键。
  • 它首先检查控制器是否为 Controller 类型,然后获取当前操作的描述符(ControllerActionDescriptor)。
  • 通过操作名称和参数生成一个唯一的缓存键。参数以 key=value 的形式连接,并用 & 分隔。
  • 返回的缓存键格式为:Namespace:ClassName:ActionName:key1=value1&key2=value2

6. GetValue 方法

  • 该方法用于获取参数的字符串表示。
  • 如果参数是一个 IEnumerable 类型(但不是字符串),则将其元素连接成一个字符串,以分号分隔。
  • 否则,直接返回参数的字符串表示。

总结

CacheAttribute 旨在为 ASP.NET Core Web API 提供缓存功能。它通过生成唯一的缓存键来标识请求,并在请求处理的不同阶段(执行前和执行后)提供钩子,以便开发者可以实现缓存的获取和存储逻辑。当前代码中尚未实现具体的缓存逻辑,但提供了一个良好的基础。

loading