Ignore url values with Outputcache
When I use outputcaching on an action method it is cached by full url, what i would like to do is cache the page but ignore some parts of the url.
Custom route defined in Global.asax:
routes.MapRoute(
"Template",
"Report/{reportid}/{reportname}/Template/{templateid}/{action}",
new { controller = "Template", action = "Index" }
);
My template controller
public class TemplateController : Controller
{
[OutputCache(Duration=60*60*2)]
public ActionResult Index(Template template)
{
/* some code */
}
}
For example when I go t开发者_StackOverflowo the following URL's:
http://mywebsite.com/Report/789/cacheme/Template/5
-> cached for 2 hours based on the urlhttp://mywebsite.com/Report/777/anothercacheme/Template/5
-> also gets cached for 2 hours based on that urlWhat I would like is that the OutputCache ignores the reportname and reportid values so when I go to the above url's it returns the same cached version. Is this possible with the OutputCache attribute or will I have to write my custom OutputCache FilterAttribute?
Ended up with the following (inspired by 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);
}
}
精彩评论