Кэширования является неотъемлимой частью любого крупного сайта. Посмотрим как на практике реализуется кэширование в ASP.NET MVC.
Создадим следующий ActionFilter:
- using System;
- using System.Web;
- using System.Web.Mvc;
-
- public class CacheFilterAttribute : ActionFilterAttribute
- {
- /// <summary>
- /// Gets or sets the cache duration in seconds. The default is 10 seconds.
- /// </summary>
- /// <value>The cache duration in seconds.</value>
- public int Duration
- {
- get;
- set;
- }
-
- public CacheFilterAttribute()
- {
- Duration = 10;
- }
-
- public override void OnActionExecuted(FilterExecutedContext filterContext)
- {
- if (Duration <= 0) return;
-
- HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
- TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);
-
- cache.SetCacheability(HttpCacheability.Public);
- cache.SetExpires(DateTime.Now.Add(cacheDuration));
- cache.SetMaxAge(cacheDuration);
- cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
- }
- }
using System;
using System.Web;
using System.Web.Mvc;
public class CacheFilterAttribute : ActionFilterAttribute
{
/// <summary>
/// Gets or sets the cache duration in seconds. The default is 10 seconds.
/// </summary>
/// <value>The cache duration in seconds.</value>
public int Duration
{
get;
set;
}
public CacheFilterAttribute()
{
Duration = 10;
}
public override void OnActionExecuted(FilterExecutedContext filterContext)
{
if (Duration <= 0) return;
HttpCachePolicyBase cache = filterContext.HttpContext.Response.Cache;
TimeSpan cacheDuration = TimeSpan.FromSeconds(Duration);
cache.SetCacheability(HttpCacheability.Public);
cache.SetExpires(DateTime.Now.Add(cacheDuration));
cache.SetMaxAge(cacheDuration);
cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
}
}
Применяется такой ActionFilter очень просто:
- [CacheFilter(Duration = 60, Order = 2)]
- [OutputCache(Duration = 60, VaryByParam = "None", Order = 1)]
- public ActionResult Index(string alias)
[CacheFilter(Duration = 60, Order = 2)]
[OutputCache(Duration = 60, VaryByParam = "None", Order = 1)]
public ActionResult Index(string alias)
Теперь результат Index будет закэширован на 60 секунд. OutputCache отвечает за кэширование результата, а CacheFilter за заголовки возвращаемые сервером. Для сжатия данных методом gzip, подойдет следующий ActionFilter:
- using System.Web;
- using System.Web.Mvc;
-
- public class CompressFilter : ActionFilterAttribute
- {
- public override void OnActionExecuting(FilterExecutingContext filterContext)
- {
- HttpRequestBase request = filterContext.HttpContext.Request;
-
- string acceptEncoding = request.Headers["Accept-Encoding"];
-
- if (string.IsNullOrEmpty(acceptEncoding)) return;
-
- acceptEncoding = acceptEncoding.ToUpperInvariant();
-
- HttpResponseBase response = filterContext.HttpContext.Response;
-
- if (acceptEncoding.Contains("GZIP"))
- {
- response.AppendHeader("Content-encoding", "gzip");
- response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
- }
- else if (acceptEncoding.Contains("DEFLATE"))
- {
- response.AppendHeader("Content-encoding", "deflate");
- response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
- }
- }
- }
using System.Web;
using System.Web.Mvc;
public class CompressFilter : ActionFilterAttribute
{
public override void OnActionExecuting(FilterExecutingContext filterContext)
{
HttpRequestBase request = filterContext.HttpContext.Request;
string acceptEncoding = request.Headers["Accept-Encoding"];
if (string.IsNullOrEmpty(acceptEncoding)) return;
acceptEncoding = acceptEncoding.ToUpperInvariant();
HttpResponseBase response = filterContext.HttpContext.Response;
if (acceptEncoding.Contains("GZIP"))
{
response.AppendHeader("Content-encoding", "gzip");
response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
}
else if (acceptEncoding.Contains("DEFLATE"))
{
response.AppendHeader("Content-encoding", "deflate");
response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
}
}
}
Применяется следующим образом:
- [CompressFilter(Order = 3)]
- [CacheFilter(Duration = 60, Order = 2)]
- [OutputCache(Duration = 60, VaryByParam = "None", Order = 1)]
- public ActionResult Index(string alias)
[CompressFilter(Order = 3)]
[CacheFilter(Duration = 60, Order = 2)]
[OutputCache(Duration = 60, VaryByParam = "None", Order = 1)]
public ActionResult Index(string alias)
Order - порядок следования аттрибутов. В результате - ответ сервера, с кэшированием ("Cache-control: public, must-relative, proxy-revalidate, max-age=30") и сжатием ("Content-Encoding: gzip"):
Ссылки по теме
Файлы