diff --git a/WebApiClientCore/Attributes/CacheAttributes/CacheAttribute.cs b/WebApiClientCore/Attributes/CacheAttributes/CacheAttribute.cs index 8beadcc1..aa92ca30 100644 --- a/WebApiClientCore/Attributes/CacheAttributes/CacheAttribute.cs +++ b/WebApiClientCore/Attributes/CacheAttributes/CacheAttribute.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Net; +using System.Net.Http; using System.Text; using System.Threading.Tasks; using WebApiClientCore.Exceptions; @@ -14,6 +16,26 @@ namespace WebApiClientCore.Attributes [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)] public class CacheAttribute : ApiCacheAttribute { + /// + /// 非200响应时的缓存毫秒数(默认3秒,设为0则不缓存) + /// + public double ErrorExpiration { get; set; } + + /// + /// 是否允许对非 GET 请求进行缓存(默认为 false,需显式二次确认) + /// + public bool EnableNonGet { get; set; } + + /// + /// 用于在运行时存储动态计算的过期时间 + /// + private TimeSpan? _dynamicExpiration; + + /// + /// 重写 Expiration 属性,使其能返回动态调整后的值 + /// + public new TimeSpan Expiration => _dynamicExpiration ?? base.Expiration; + /// /// 缓存键的请求头名称 /// @@ -38,9 +60,75 @@ public string? IncludeHeaders /// 使用缓存的特性 /// /// 缓存毫秒数 - public CacheAttribute(double expiration) + /// 接口异常时 缓存毫秒数,默认:3秒 + /// 是否允许对非 GET 请求进行缓存 + public CacheAttribute(double expiration, double errorExpiration = 3000, bool enableNonGet = false) : base(expiration) { + this.ErrorExpiration = errorExpiration; + this.EnableNonGet = enableNonGet; + } + + /// + /// + /// + /// + /// + public override CachePolicy GetWritePolicy(ApiRequestContext context) + { + var request = context.HttpContext.RequestMessage; + var response = context.HttpContext.ResponseMessage; + + // 判断是否为非 GET 方法 + if (request.Method != HttpMethod.Get) + { + if (!this.EnableNonGet) + { + // 输出请求路径和方法,提醒开发者该非GET请求已被跳过缓存 + Console.WriteLine($"[WARN] Cache Ignored: Method {request.Method} on {request.RequestUri} requires 'EnableNonGet=true'."); + return CachePolicy.Ignore; + } + else + { + // 表示这是特殊处理的非GET缓存 + Console.WriteLine($"[INFO] Cache Enabled for Non-GET: {request.RequestUri}"); + } + } + + // 接口升级/异常状态(非 200) + if (response != null && response.StatusCode != HttpStatusCode.OK) + { + if (this.ErrorExpiration <= 0) + { + return CachePolicy.Ignore; + } + + // 动态记录短缓存时间 + _dynamicExpiration = TimeSpan.FromMilliseconds(this.ErrorExpiration); + return CachePolicy.Include; + } + + // 200 OK 正常情况 + _dynamicExpiration = null; // 恢复使用 base.Expiration + return CachePolicy.Include; + } + + /// + /// + /// + /// + /// + public override CachePolicy GetReadPolicy(ApiRequestContext context) + { + var request = context.HttpContext.RequestMessage; + // 如果不是 GET 且没有明确开启非GET支持 + if (request.Method != HttpMethod.Get && !this.EnableNonGet) + { + // 跳过之前的缓存 + Console.WriteLine($"[WARN] Cache Ignored: Method {request.Method} on {request.RequestUri} requires 'EnableNonGet=true'."); + return CachePolicy.Ignore; + } + return CachePolicy.Include; } ///