2009-03-03 23 views
7

मेरे पास एक व्यूपेज है जिसमें <% Html.RenderAction<MyController>(c => c.SidebarStats()); %> है। कार्रवाई के लिए नियंत्रक कार्रवाई पर SidebarStats मेरे पास पृष्ठ के केवल उस हिस्से को कैश करने के लिए आउटपुट कैश एक्शन फ़िल्टर है। हालांकि, पूरा पृष्ठ कैश हो रहा है और न केवल उस क्रिया को।आउटपुट कैश और रेंडरएक्शन कैश पूरे पृष्ठ

मुझे कहीं याद है कि यह एएसपी.नेट एमवीसी के साथ एक बग हो सकता है हालांकि मुझे यकीन नहीं है। मैं वर्तमान में एएसपी.नेट एमवीसी आरसी 1, आईआईएस 7, विंडोज सर्वर 2008 और .NET 3.5 एसपी 1 का उपयोग कर रहा हूं।

उत्तर

10

मैंने solution to this problem here ब्लॉग किया। यह आसान है, लेकिन यह केवल तभी काम करता है जब आप WebFormViewEngine का उपयोग कर रहे हों। हम सभी व्यू इंजनों के लिए यह काम करने के लिए क्या करेंगे, यह जानने में हम कड़ी मेहनत करेंगे।

+0

आप आदमी फिल, मुझे पता था कि वहां एक सुरुचिपूर्ण समाधान होना चाहिए था। धन्यवाद! –

+2

क्या यह बग V2 में तय है? – CVertex

+1

@CVertex संख्या। क्या यह रेजर व्यू इंजन के साथ काम कर रहे वी 3 में तय किया जाएगा? – stacker

2

माइक्रोसॉफ्ट के अनुसार यह ज्ञात फिक्स के साथ ज्ञात बग है। सुझाए गए केवल कामकाज ही आपके आउटपुट कैश एक्शन फ़िल्टर को बनाने के लिए हैं।

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

यह मेरे लिए अच्छा लग रहा है! मुझे लगता है कि मैं कोशिश करूँगा! –

संबंधित मुद्दे