2013-01-10 7 views
1

Атрибут OutputCache при действии, который возвращает Json, не работает - когда я ударил URL-адрес действия в браузере много раз, каждый раз, когда я получил точку останова, активированную в VS2012 (это похоже, что атрибут OutputCache игнорируется). Вот мой код:Outputcache не работает для JsonResult (asp.net-mvc-3)

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 наследуется от контроллера. В других контроллерах, наследующих от GenericControllerBase, OutputCache работает так, как ожидалось, но они возвращают View() вместо Json. В качестве эксперимента я добавил параметр VaryByCustom и установил, что метод GetVaryByCustomString в файле global.asax также не попал, поэтому функциональность кэширования полностью игнорируется. Я использую MVC3 и autofac для инъекций (но другие контроллеры, использующие автоматическую инъекцию, работают правильно с OutputCache).

В чем может быть проблема? Что может блокировать функциональность OutputCache? Возможно ли, что это имеет какое-то отношение к кешированию всего ответа? Все остальные действия с использованием OutputCache в моих проектах - это частичные действия, вложенные в @ Html.Action (...) в представлениях.

Каков наилучший способ кэшировать весь ответ Json на действие GET в MVC3?

Update

После нескольких тестов оказалось, что OutputCache игнорируется для действий возвращающимся полных страниц (не только JSON). Кэш работает только для дочерних операций в моем проекте. Что может быть причиной?

ответ

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 пути и запроса на данный момент времени, и она работает, как ожидалось.

Смежные вопросы