出處:http://www.cnblogs.com/ajilisiwei/p/6112078.html
原文的轉載地址:http://www.strathweb.com/2012/05/output-caching-in-asp-net-web-api/
一.Nuget安裝相關dll
Web API 2 : Install-Package Strathweb.CacheOutput.WebApi2
Web API 1 : Install-Package Strathweb.CacheOutput
二.新建一個 ActionFilterAttribute ,並重寫相關方法
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");
}
}
//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();
}
}
三. 控制器的需要添加緩存的Get方法添加該過濾器
[WebApiOutputCache(120,60,false)]
public string GetShoppingCart()
{
return "Hello World";
}
啟動,觀察打斷點,觀察效果。整個過程是:啟動時先初始化該緩存過濾器,客戶端調用添加了該過濾器的Get方法后,進入OnActionExecuting方法,判斷是否有相關的緩存存在,如果有則直接返回結果,如否,則調用控制器的Action,再調用OnActionExecuted方法添加相關的緩存鍵值對並設置緩存過期時間,返回結果。