1. Nuget installs the relevant dll
Web API 2 : Install-Package Strathweb.CacheOutput.WebApi2 Web API 1 : Install-Package Strathweb.CacheOutput
Two. Create a new ActionFilterAttribute and override the related methods
public class WebApiOutputCacheAttribute : ActionFilterAttribute { Cache time/sec private int _timespan; Client cache time/sec private int _clientTimeSpan; Whether it is cached by anonymous users private bool _anonymousOnly; Cache the index key private string _cachekey; Cache warehouses 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"); } }
//Action调用后执行方法 public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext) { if (!( WebApiCache.Contains(_cachekey))) { var body = actionExecutedContext.Response.Content.ReadAsStringAsync(). Result; WebApiCache.Add(_cachekey, body, DateTime.Now.AddSeconds(_timespan)); WebApiCache.Add(_cachekey + ":response-ct", actionExecutedContext.Response.Content.Headers.ContentType, DateTime.Now.AddSeconds(_timespan)); } if (_isCacheable(actionExecutedContext.ActionContext)) actionExecutedContext.ActionContext.Response.Headers.CacheControl = setClientCache(); }
}
3. The controller needs to add the cache to the Get method to add the filter
[WebApiOutputCache(120,60,false)] public string GetShoppingCart() { return "Hello World"; } start, observe the breakpoint, and observe the effect. The whole process is: initialize the cache filter at startup, and then call the Get method with the filter added, enter the OnActionExecuting method, determine whether there is a relevant cache, if there is, return the result directly, if not, call the controller's Action, and then call the OnActionExecuted method to add the relevant cache key-value pair and set the cache expiration time to return the result. |