OutputCache behavior in ASP.NET MVC 3

自古美人都是妖i 提交于 2019-12-02 18:53:21

Just wanted to add this information so that people searching are helped:

The OutputCache behavior has been changed to be 'as expected' in the latest release (ASP.NET MVC 3 RC 2):

http://weblogs.asp.net/scottgu/archive/2010/12/10/announcing-asp-net-mvc-3-release-candidate-2.aspx

Way to go ASP.NET MVC team (and Master Gu)! You all are awesome!

VaryByParam only works when the values of the url look like /user/view?slug=abc. The params must be a QueryString parameter and not part of the url like your above examples. The reason for this is most likely because Caching happens before any url mapping and that mapping isn't included in the cache.

Update

The following code will get you where you want to go. It doesn't take into account stuff like Authorized filters or anything but it will cache based on controller/action/ids but if you set ignore="slug" it will ignore that particular attribute

public class ActionOutputCacheAttribute : ActionFilterAttribute {
    public ActionOutputCacheAttribute(int cacheDuration, string ignore) {
        this.cacheDuration = cacheDuration;
        this.ignore = ignore;
    }

    private int cacheDuration;
    private string cacheKey;
    private string ignore;

    public override void OnActionExecuting(ActionExecutingContext filterContext) {
        string url = filterContext.HttpContext.Request.Url.PathAndQuery;
        this.cacheKey = ComputeCacheKey(filterContext);

        if (filterContext.HttpContext.Cache[this.cacheKey] != null) {
            //Setting the result prevents the action itself to be executed
            filterContext.Result =
            (ActionResult)filterContext.HttpContext.Cache[this.cacheKey];
        }

        base.OnActionExecuting(filterContext);
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext) {
        //Add the ActionResult to cache 
        filterContext.HttpContext.Cache.Add(this.cacheKey, filterContext.Result,null, DateTime.Now.AddSeconds(cacheDuration),
          System.Web.Caching.Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);

        //Add a value in order to know the last time it was cached.
        filterContext.Controller.ViewData["CachedStamp"] = DateTime.Now;

        base.OnActionExecuted(filterContext);
    }

    private string ComputeCacheKey(ActionExecutingContext filterContext) {
        var keyBuilder = new StringBuilder();
        keyBuilder.Append(filterContext.ActionDescriptor.ControllerDescriptor.ControllerName);
        keyBuilder.Append(filterContext.ActionDescriptor.ActionName);

        foreach (var pair in filterContext.RouteData.Values) {
            if (pair.Key != ignore) 
                keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
        }
        return keyBuilder.ToString();
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!