代码之家  ›  专栏  ›  技术社区  ›  Chad Moran

OutputCache和RenderAction缓存整个页面

  •  7
  • Chad Moran  · 技术社区  · 17 年前

    <% Html.RenderAction<MyController>(c => c.SidebarStats()); %>

    我记得在某个地方看到这可能是ASP的一个bug。NET MVC,但我不确定。我目前正在使用ASP。NET MVC RC1、IIS7、Windows Server 2008和。净3.5 SP1。

    3 回复  |  直到 17 年前
        1
  •  10
  •   Haacked    17 年前

    我写了一篇博客 solution to this problem here 。这很简单,但只有在使用WebFormViewEngine时才有效。我们将努力研究如何使它适用于所有视图引擎。

        2
  •  2
  •   Chad Moran    17 年前

    据微软称,这是一个已知的错误,没有已知的修复方法。建议的唯一解决方法是创建自己的OutputCache操作过滤器。

        3
  •  0
  •   Bouke    6 年前

    我现在使用什么 史蒂夫·桑德森 制造于 his blog

    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();
        }
    }
    

    请访问 Steve Sanderson blog's article