2009-03-03 18 views
7

Ho una ViewPage che contiene <% Html.RenderAction<MyController>(c => c.SidebarStats()); %>. Sull'azione del controller per l'azione SidebarStats ho un filtro di azione OutputCache per memorizzare solo quella parte della pagina. Tuttavia, l'intera pagina viene memorizzata nella cache e non solo quella azione.OutputCache e RenderAction cache intera pagina

Ricordo di aver visto da qualche parte che questo potrebbe essere un bug con ASP.NET MVC anche se non ne sono sicuro. Attualmente sto utilizzando ASP.NET MVC RC1, IIS7, Windows Server 2008 e .NET 3.5 SP1.

risposta

10

Ho bloggato un solution to this problem here. È semplice, ma funziona solo se stai utilizzando WebFormViewEngine. Faremo molta attenzione a capire cosa servirà per far funzionare tutto questo per tutti i motori di visualizzazione.

+0

Tu l'uomo Phil, sapevo che doveva esserci una soluzione elegante. Grazie! –

+2

Questo bug è stato risolto in V2? – CVertex

+1

@CVertex no. Questo problema verrà risolto in V3, lavorando con il motore di visualizzazione Razor? – stacker

2

Secondo Microsoft questo è un bug noto senza correzioni note. Solo soluzioni alternative suggerite sono per creare il proprio filtro di azione OutputCache.

0

Ora sto utilizzando quello Steve Sanderson fatto in his blog ed è molto bello:

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

Si prega di visitare Steve Sanderson blog's article per ulteriori informazioni.

+0

Mi sembra buono! Penso che lo proverò! –

Problemi correlati