ASP.Net Web API 输出缓存 转载

时间:2022-04-16 00:49:35

public class WebApiOutputCacheAttribute : ActionFilterAttribute
    {
        // 缓存时间 /秒
        private int _timespan;
        // 客户端缓存时间 /秒
        private int _clientTimeSpan;
        // 是否为匿名用户缓存
        private bool _anonymousOnly;
        // 缓存索引键
        private string _cachekey;
        // 缓存仓库
        private static readonly ObjectCache WebApiCache = MemoryCache.Default;


        public WebApiOutputCacheAttribute(int timespan, int clientTimeSpan, bool anonymousOnly)
        {
          _timespan = timespan;
          _clientTimeSpan = clientTimeSpan;
          _anonymousOnly = anonymousOnly;
        }

//是否缓存
        private bool _isCacheable(HttpActionContext ac)
        {
             if (_timespan > 0 && _clientTimeSpan > 0)
             {
                if (_anonymousOnly)
                   if (Thread.CurrentPrincipal.Identity.IsAuthenticated)
                         return false;
               if (ac.Request.Method == HttpMethod.Get) return true;
            }
           else
           {
                throw new InvalidOperationException("Wrong Arguments");
           }
            return false;
        }

private CacheControlHeaderValue setClientCache()
        {
            var cachecontrol = new CacheControlHeaderValue();
            cachecontrol.MaxAge = TimeSpan.FromSeconds(_clientTimeSpan);
            cachecontrol.MustRevalidate = true;
            return cachecontrol;
        }
 

//Action调用前执行的方法
        public override void OnActionExecuting(HttpActionContext ac)
        {
            if (ac != null)
            {
                if (_isCacheable(ac))
                {
                    _cachekey = string.Join(":", new string[] { ac.Request.RequestUri.AbsolutePath, ac.Request.Headers.Accept.FirstOrDefault().ToString() });
                    if (WebApiCache.Contains(_cachekey))
                    {
                        var val = (string)WebApiCache.Get(_cachekey);
                        if (val != null)
                        {
                            ac.Response = ac.Request.CreateResponse();
                            ac.Response.Content = new StringContent(val);
                            var contenttype = (MediaTypeHeaderValue)WebApiCache.Get(_cachekey + ":response-ct");
                            if (contenttype == null)
                                contenttype = new MediaTypeHeaderValue(_cachekey.Split(‘:‘)[1]);
                            ac.Response.Content.Headers.ContentType = contenttype;
                            ac.Response.Headers.CacheControl = setClientCache();
                            return;
                        }
                    }
                }
            }
            else
            {
                throw new ArgumentNullException("actionContext");
            }
        }