我正在尝试在Web API中缓存ApiController方法的输出。
这是控制器代码:
public class TestController : ApiController
{
[OutputCache(Duration = 10, VaryByParam = "none", Location = OutputCacheLocation.Any)]
public string Get()
{
return System.DateTime.Now.ToString();
}
}
N.B。我还尝试了控制器本身的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的限制还是我做错了什么?
答案 0 :(得分:39)
WebAPI没有[OutputCache]
属性的内置支持。以a look at this article为例,了解如何自行实施此功能。
答案 1 :(得分:32)
Aliostad的答案表明Web API关闭了缓存,HttpControllerHandler的代码显示它确实在响应时.Headers.CacheControl为空。
要使您的示例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
...
答案 2 :(得分:15)
在过去的几个月里,我一直致力于ASP.NET Web API的HTTP缓存。我已为WebApiContrib提供服务器方面的相关信息,我可以在blog找到相关信息。
最近,我开始扩展工作,并在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);
}
答案 3 :(得分:2)
我很晚,但仍然想在WebApi上发布这篇关于缓存的文章
https://codewala.net/2015/05/25/outputcache-doesnt-work-with-web-api-why-a-solution/
[CacheWebApi(Duration = 20)]
public IEnumerable<string> Get()
{
return new string[] { DateTime.Now.ToLongTimeString(), DateTime.UtcNow.ToLongTimeString() };
}
在上面的代码中,我们重写了OnActionExecuted方法并在响应中设置了所需的标头。现在我将Web API调用装饰为
ltrim(UOM) = 'PK'
答案 4 :(得分:-21)
您可以在常规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中不可用。