[英]Output caching for an ApiController (MVC4 Web API)
我正在嘗試在Web API中緩存ApiController方法的輸出。
這是控制器代碼:
public class TestController : ApiController
{
[OutputCache(Duration = 10, VaryByParam = "none", Location = OutputCacheLocation.Any)]
public string Get()
{
return System.DateTime.Now.ToString();
}
}
NB我還嘗試了控制器本身的OutputCache屬性,以及它的幾個參數組合。
該路線在Global.asax中注冊:
namespace WebApiTest
{
public class Global : HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.MapHttpRoute("default", routeTemplate: "{controller}");
}
}
}
我得到了一個成功的回復,但它沒有緩存在任何地方:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Wed, 18 Jul 2012 17:56:17 GMT
Content-Length: 96
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">18/07/2012 18:56:17</string>
我無法在Web API中找到輸出緩存的文檔。
這是MVC4中Web API的限制還是我做錯了什么?
WebAPI沒有對[OutputCache]
屬性的任何內置支持。 看看這篇文章 ,了解如何自己實現此功能。
Aliostad的答案表明Web API關閉了緩存,而HttpControllerHandler的代碼顯示它確實在響應時.Headers.CacheControl為null。
要使您的示例ApiController Action返回可緩存的結果,您可以:
using System.Net.Http;
public class TestController : ApiController
{
public HttpResponseMessage Get()
{
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(System.DateTime.Now.ToString());
response.Headers.CacheControl = new CacheControlHeaderValue();
response.Headers.CacheControl.MaxAge = new TimeSpan(0, 10, 0); // 10 min. or 600 sec.
response.Headers.CacheControl.Public = true;
return response;
}
}
你會得到一個像這樣的HTTP響應頭:
Cache-Control: public, max-age=600
Content-Encoding: gzip
Content-Type: text/plain; charset=utf-8
Date: Wed, 13 Mar 2013 21:06:10 GMT
...
在過去的幾個月里,我一直致力於ASP.NET Web API的HTTP緩存。 我為WebApiContrib貢獻了服務器端,相關信息可以在我的博客上找到。
最近我開始擴展工作並在CacheCow庫中添加客戶端。 第一批NuGet套餐現已發布(感謝Tugberk )更多內容。 我很快就會寫一篇博文。 所以看空間。
但為了回答您的問題,ASP.NET Web API默認關閉緩存。 如果希望緩存響應,則需要將CacheControl標頭添加到控制器中的響應中(實際上最好是在類似於CacheCow中的CachingHandler的委托處理程序中)。
這個片段來自ASP.NET Web Stack源代碼中的HttpControllerHandler
:
CacheControlHeaderValue cacheControl = response.Headers.CacheControl;
// TODO 335085: Consider this when coming up with our caching story
if (cacheControl == null)
{
// DevDiv2 #332323. ASP.NET by default always emits a cache-control: private header.
// However, we don't want requests to be cached by default.
// If nobody set an explicit CacheControl then explicitly set to no-cache to override the
// default behavior. This will cause the following response headers to be emitted:
// Cache-Control: no-cache
// Pragma: no-cache
// Expires: -1
httpContextBase.Response.Cache.SetCacheability(HttpCacheability.NoCache);
}
我很晚,但仍然想在WebApi上發布這篇關於緩存的文章
https://codewala.net/2015/05/25/outputcache-doesnt-work-with-web-api-why-a-solution/
public class CacheWebApiAttribute : ActionFilterAttribute
{
public int Duration { get; set; }
public override void OnActionExecuted(HttpActionExecutedContext filterContext)
{
filterContext.Response.Headers.CacheControl = new CacheControlHeaderValue()
{
MaxAge = TimeSpan.FromMinutes(Duration),
MustRevalidate = true,
Private = true
};
}
}
在上面的代碼中,我們重寫了OnActionExecuted方法並在響應中設置了所需的標頭。 現在我將Web API調用裝飾為
[CacheWebApi(Duration = 20)]
public IEnumerable<string> Get()
{
return new string[] { DateTime.Now.ToLongTimeString(), DateTime.UtcNow.ToLongTimeString() };
}
您可以在常規MVC控制器上使用它:
[OutputCache(Duration = 10, VaryByParam = "none", Location = OutputCacheLocation.Any)]
public string Get()
{
HttpContext.Current.Response.Cache.SetOmitVaryStar(true);
return System.DateTime.Now.ToString();
}
但OutputCache屬性位於System.Web.Mvc命名空間中,在ApiController中不可用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.