OutputCache и RenderAction кэшируют всю страницу - PullRequest
7 голосов
/ 03 марта 2009

У меня есть ViewPage, которая содержит <% Html.RenderAction<MyController>(c => c.SidebarStats()); %>. В действии контроллера для действия SidebarStats у меня есть фильтр действия OutputCache для кэширования только этой части страницы. Однако вся страница кэшируется, а не только это действие.

Я помню, как где-то видел, что это может быть ошибка в ASP.NET MVC, хотя я не уверен. В настоящее время я использую ASP.NET MVC RC1, IIS7, Windows Server 2008 и .NET 3.5 SP1.

Ответы [ 3 ]

10 голосов
/ 13 мая 2009

Я разместил в блоге решение этой проблемы здесь . Это просто, но работает, только если вы используете WebFormViewEngine. Мы постараемся выяснить, что потребуется, чтобы сделать эту работу для всех механизмов представления.

2 голосов
/ 03 марта 2009

По словам Microsoft, это известная ошибка без известных исправлений. Только предложенные обходные пути - создать собственный фильтр действий OutputCache.

0 голосов
/ 04 октября 2010

Я сейчас использую то, что Стив Сандерсон сделал в его блоге , и это очень приятно:

public class ActionOutputCacheAttribute : ActionFilterAttribute
{
    // This hack is optional; I'll explain it later in the blog post
    private static readonly MethodInfo _switchWriterMethod = typeof (HttpResponse).GetMethod("SwitchWriter",
                                                                                             BindingFlags.Instance |
                                                                                             BindingFlags.NonPublic);

    private readonly int _cacheDuration;
    private string _cacheKey;
    private TextWriter _originalWriter;

    public ActionOutputCacheAttribute(int cacheDuration)
    {
        _cacheDuration = cacheDuration;
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        _cacheKey = ComputeCacheKey(filterContext);
        var cachedOutput = (string) filterContext.HttpContext.Cache[_cacheKey];
        if (cachedOutput != null)
            filterContext.Result = new ContentResult {Content = cachedOutput};
        else
            _originalWriter =
                (TextWriter)
                _switchWriterMethod.Invoke(HttpContext.Current.Response,
                                           new object[] {new HtmlTextWriter(new StringWriter())});
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        if (_originalWriter != null) // Must complete the caching
        {
            var cacheWriter =
                (HtmlTextWriter)
                _switchWriterMethod.Invoke(HttpContext.Current.Response, new object[] {_originalWriter});
            string textWritten = (cacheWriter.InnerWriter).ToString();
            filterContext.HttpContext.Response.Write(textWritten);

            filterContext.HttpContext.Cache.Add(_cacheKey, textWritten, null,
                                                DateTime.Now.AddSeconds(_cacheDuration), Cache.NoSlidingExpiration,
                                                CacheItemPriority.Normal, null);
        }
    }

    private string ComputeCacheKey(ActionExecutingContext filterContext)
    {
        var keyBuilder = new StringBuilder();
        foreach (var pair in filterContext.RouteData.Values)
            keyBuilder.AppendFormat("rd{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
        foreach (var pair in filterContext.ActionParameters)
            keyBuilder.AppendFormat("ap{0}_{1}_", pair.Key.GetHashCode(), pair.Value.GetHashCode());
        return keyBuilder.ToString();
    }
}

Пожалуйста, посетите статью блога Стива Сандерсона для получения дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...