2009-03-03 9 views
7

私は<% Html.RenderAction<MyController>(c => c.SidebarStats()); %>を含むViewPageを持っています。 SidebarStatsアクションのコントローラーアクションでは、ページのその部分だけをキャッシュするOutputCacheアクションフィルターがあります。しかし、ページ全体がキャッシュされ、そのアクションだけではありません。OutputCacheとRenderActionのキャッシュ全体のページ

わかりませんが、これはASP.NET MVCのバグかもしれないと思いました。私は現在、ASP.NET MVC RC1、IIS7、Windows Server 2008、および.NET 3.5 SP1を使用しています。

答えて

10

私はブログsolution to this problem hereをブログに投稿しました。シンプルですが、WebFormViewEngineを使用している場合にのみ機能します。私たちは、すべてのビューエンジンでこの作業を行うために必要なことを理解していきます。

+0

あなたは男のPhilです。私はエレガントな解決策がなければならないことを知っていました。ありがとう! –

+2

このバグはV2で修正されていますか? – CVertex

+1

@CVertex no。これは、Razorビューエンジンで作業するV3で修正されますか? – stacker

2

Microsoftによると、これは既知の不具合のある既知のバグです。提案された回避策は、独自のOutputCacheアクションフィルタを作成することだけです。

0

私は今スティーブサンダーソン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をご覧ください。

+0

これは私によく見えます!私はそれを試みると思う! –

関連する問題