Игнорировать значения URL с помощью Outputcache

Когда я использую outputcaching для метода действия, он кэшируется по полному URL-адресу, и я хотел бы кэшировать страницу, но игнорировать некоторые части URL-адреса.

Пользовательский маршрут, определенный в Global.asax:

routes.MapRoute(
  "Template",
  "Report/{reportid}/{reportname}/Template/{templateid}/{action}",
  new { controller = "Template", action = "Index" }
);

Мой контроллер шаблонов

public class TemplateController : Controller
{
   [OutputCache(Duration=60*60*2)]
   public ActionResult Index(Template template)
   {
      /* some code */
   }
}

Например, когда я перехожу к следующим URL-адресам:

http://mywebsite.com/Report/789/cacheme/Template/5
-> кешируется на 2 часа на основе URL

http://mywebsite.com/Report/777/anothercacheme/Template/5
-> также кэшируется на 2 часа на основе этого URL

Я бы хотел, чтобы OutputCache игнорировал значения reportname и reportid, поэтому, когда я перехожу по указанному выше URL-адресу, он возвращает та же кэшированная версия. Возможно ли это с помощью атрибута OutputCache или мне придется написать собственный атрибут OutputCache FilterAttribute?


person jeroen.verhoest    schedule 14.04.2011    source источник
comment
Возможно, одним из способов может быть сделать reportname, reportid параметрами вашего метода, а затем использовать VaryByParam только для templateid. Помимо этого, настраиваемый атрибут фильтра будет кстати!   -  person VinayC    schedule 14.04.2011
comment
Я пробовал, но он по-прежнему возвращает разные кешированные версии для запрошенного шаблона.   -  person jeroen.verhoest    schedule 14.04.2011


Ответы (1)


В итоге получилось следующее (на основе http://blog.stevensanderson.com/2008/10/15/partial-output-caching-in-aspnet-mvc/):

 public class ResultCacheAttribute : ActionFilterAttribute
    {
        public ResultCacheAttribute()
        {

        }

        public string CacheKey
        {
            get;
            private set;
        }

        public bool AddUserCacheKey { get; set; }
        public bool IgnoreReport { get; set; }

        /// <summary>
        /// Duration in seconds of the cached values before expiring.
        /// </summary>
        public int Duration
        {
            get;
            set;
        }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            string url = "";
            foreach (var item in filterContext.RouteData.Values)
            {
                if (IgnoreReport)
                    if (item.Key == "reportid" || item.Key == "reportname")
                        continue;

                url += "." + item.Value;
            }
            if (AddUserCacheKey)
                url += "." + filterContext.HttpContext.User.Identity.Name;

            this.CacheKey = "ResultCache-" + url;

            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
                this.CacheKey += "-ajax";

            if (filterContext.HttpContext.Cache[this.CacheKey] != null)
            {
                filterContext.Result = (ActionResult)filterContext.HttpContext.Cache[this.CacheKey];
            }
            else
            {
                base.OnActionExecuting(filterContext);
            }
        }

        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            filterContext.Controller.ViewData["CachedStamp"] = DateTime.Now;
            filterContext.HttpContext.Cache.Add(this.CacheKey, filterContext.Result, null, DateTime.Now.AddSeconds(Duration), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);

            base.OnActionExecuted(filterContext);
        }
    }
person jeroen.verhoest    schedule 18.04.2011