网站首页 网站源码
#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()!;
}
}
这段代码定义了一个名为 CacheAttribute
的 ASP.NET Core 中间件特性(Attribute),用于在 Web API 中实现缓存功能。下面是对代码的详细解释:
CacheAttribute
继承自 ActionFilterAttribute
,这意味着它可以在控制器的操作方法执行前后进行处理。AttributeTargets.Method | AttributeTargets.Class
)。CurrentRequestCacheKey
是一个字符串常量,用于在 HTTP 上下文中存储当前请求的缓存键。OnActionExecutionAsync
方法key
),如果键为空,则直接返回。HttpContext.Items
中,以便在后续处理中使用。ICacheClient
),并在此处实现缓存的获取逻辑。base.OnActionExecutionAsync(context, next)
继续执行后续的操作。OnResultExecutionAsync
方法GeneratorCacheKey
方法Controller
类型,然后获取当前操作的描述符(ControllerActionDescriptor
)。key=value
的形式连接,并用 &
分隔。Namespace:ClassName:ActionName:key1=value1&key2=value2
。GetValue
方法IEnumerable
类型(但不是字符串),则将其元素连接成一个字符串,以分号分隔。CacheAttribute
旨在为 ASP.NET Core Web API 提供缓存功能。它通过生成唯一的缓存键来标识请求,并在请求处理的不同阶段(执行前和执行后)提供钩子,以便开发者可以实现缓存的获取和存储逻辑。当前代码中尚未实现具体的缓存逻辑,但提供了一个良好的基础。