2009-03-03 28 views
7

Tengo una página de vista que contiene <% Html.RenderAction<MyController>(c => c.SidebarStats()); %>. En la acción del controlador para la acción SidebarStats, tengo un filtro de acción OutputCache para almacenar solo esa parte de la página. Sin embargo, toda la página se almacena en caché y no solo esa acción.OutputCache y RenderAction caché toda la página

Recuerdo haber visto en algún lado que esto podría ser un error con ASP.NET MVC aunque no estoy seguro. Actualmente estoy usando ASP.NET MVC RC1, IIS7, Windows Server 2008 y .NET 3.5 SP1.

Respuesta

10

Me blogged un solution to this problem here. Es simple, pero solo funciona si usa WebFormViewEngine. Analizaremos con detalle qué se necesitará para que esto funcione en todos los motores de visualización.

+0

Tú, el hombre Phil, sabía que tenía que haber una solución elegante. ¡Gracias! –

+2

¿Este error está solucionado en V2? – CVertex

+1

@CVertex no. ¿Esto se solucionará en V3, trabajando con Razor view engine? – stacker

2

Según Microsoft, este es un error conocido sin solución conocida. Solo se sugieren soluciones alternativas para crear su propio filtro de acción OutputCache.

0

ahora estoy usando lo Steve Sanderson hizo en his blog y es muy agradable:

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

favor visite Steve Sanderson blog's article para más información.

+0

¡Esto se ve bien para mí! ¡Creo que lo intentaré! –

Cuestiones relacionadas