Outputcache不适用于JsonResult(asp.net-mvc-3)

时间:2013-01-10 19:34:24

标签: .net json asp.net-mvc-3 caching outputcache

返回Json的操作的OutputCache属性不起作用 - 当我在浏览器中多次点击操作URL时,每次我在VS2012中激活断点时(看起来忽略了OutputCache属性)。这是我的代码:

public class ApiController : GenericControllerBase
{

    [OutputCache(Duration = 300, VaryByParam = "type;showEmpty;sort;platform")]
    public JsonResult GetCategories(string type, bool? showEmpty, string sort, string platform)
    {
        ///... creating categoryResults object
        return Json(new ApiResult() { Result = categoryResults }, JsonRequestBehavior.AllowGet);
    }

}   

GenericControllerBase继承自Controller。在继承自GenericControllerBase的其他控制器中,OutputCache按预期工作,但它们返回View()而不是Json。 作为实验,我添加了VaryByCustom参数并检查了global.asax文件中的GetVaryByCustomString方法是否也未被命中,因此完全忽略了缓存功能。 我使用MVC3和autofac进行服务注入(但使用autofac注入的其他控制器与OutputCache一起正常工作)。

可能是什么问题?什么可以阻止OutputCache功能?是否有可能与缓存整个响应有关?在我的项目中使用OutputCache的所有其他操作都是在视图中嵌入@ Html.Action(...)的部分操作。

在MVC3中缓存整个Json响应的最佳方法是什么?

更新

经过一些测试后发现,返回完整页面的操作(不仅是json)会忽略OutputCache。缓存仅适用于项目中的子进程。可能是什么原因?

1 个答案:

答案 0 :(得分:4)

最终我使用MVC3的变通方法忽略了OutputCache属性。我使用自定义操作过滤器进行缓存:

public class ManualActionCacheAttribute : ActionFilterAttribute
{
    public ManualActionCacheAttribute()
    {
    }

    public int Duration { get; set; }

    private string cachedKey = null;

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string key = filterContext.HttpContext.Request.Url.PathAndQuery;
        this.cachedKey = "CustomResultCache-" + key;
        if (filterContext.HttpContext.Cache[this.cachedKey] != null)
        {
            filterContext.Result = (ActionResult)filterContext.HttpContext.Cache[this.cachedKey];
        }
        else
        {
            base.OnActionExecuting(filterContext);
        }
    }

    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        filterContext.HttpContext.Cache.Add(this.cachedKey, filterContext.Result, null, DateTime.Now.AddSeconds(Duration), System.Web.Caching.Cache.NoSlidingExpiration, System.Web.Caching.CacheItemPriority.Default, null);
        base.OnActionExecuted(filterContext);
    }
}

上面的属性根据确切的URL路径和查询在给定时间内缓存请求,并且按预期工作。