1

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 は期待どおりに機能しますが、Json ではなく View() を返します。実験的に VaryByCustom パラメータを追加し、global.asax ファイルの GetVaryByCustomString メソッドもヒットしないことを確認したため、キャッシュ機能は完全に無視されます。私は MVC3 と autofac をサービス インジェクションに使用しています (ただし、autofac インジェクションを使用する他のコントローラーは OutputCache で適切に動作します)。

何が問題なのですか?OutputCache 機能をブロックするものは何ですか? 応答全体をキャッシュすることと関係がある可能性はありますか? 私のプロジェクトで OutputCache を使用する他のすべてのアクションは、ビューに @Html.Action(...) で埋め込まれた部分的なアクションです。

MVC3のGETアクションでJsonレスポンス全体をキャッシュする最良の方法は何ですか?

アップデート

いくつかのテストの後、(json だけでなく) 完全なページを返すアクションでは OutputCache が無視されることが判明しました。キャッシュは、プロジェクトの子アクションに対してのみ機能します。原因は何ですか?

4

1 に答える 1

5

最終的に、OutputCache 属性を無視する MVC3 の回避策を使用しました。キャッシュにカスタム アクション フィルターを使用しました。

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 パスと特定の時間のクエリに基づいてリクエストをキャッシュし、期待どおりに機能します。

于 2013-01-17T11:34:10.150 に答える