2009-05-15 10 views
11

तोड़ने के बिना एएसपी.नेट एमवीसी में [कंप्रेसफ़िल्टर] का उपयोग कर सकता हूं। मैं डोनट कैशिंग के साथ काम करने और मुद्दों में चलने के लिए [CompressFilter] प्राप्त करने की कोशिश कर रहा हूं।क्या मैं डोनट कैशिंग

क्या होता है कि पूरा पृष्ठ कैश हो जाता है न केवल डोनट। मैं उपयोग कर रहा हूँ CompressFilter के लिए स्रोत नीचे है। मैंने इसे से का उपयोग OnActionExecuting() के बजाय OnResultExecuted का उपयोग करने के लिए बदल दिया क्योंकि मुझे कुछ एक्शन रिसेट उप-वर्गों को कैशिंग से बचने के लिए परिणाम के प्रकार तक पहुंच की आवश्यकता थी।

OutputCacheAttribute के लिए वास्तविक MVC v1 स्रोत कोड ऐसा लगता है कि यह भी OnResultExecuted() उपयोग कर रहा है को देखते हुए, लेकिन मुझे लगता है न कि तथ्य सीधे संघर्ष खड़ी कर रहा है।

मुझे पर्याप्त जानकारी नहीं है कि प्रतिस्थापन कैशिंग कैसे समझता है कि यह किस तरह से व्यवहार करता है। मुझे लगता है कि यह कहना उल्लेखनीय है कि यह किसी भी तरह के दूषित प्रदर्शन के साथ खत्म नहीं होता है। यह सिर्फ व्यवहार करता है जैसे कोई डोनट नहीं है!

ऐसा लगता है कि मुझे कैशिंग को संभालने के लिए किसी प्रकार के IIs प्लग-इन का उपयोग करना होगा, जिसे मैं वास्तव में करना चाहता था, लेकिन ऐसा लगता है कि मुझे डोनट कैशिंग की भी आवश्यकता है।

मैं वास्तव में यह जानना चाहता हूं कि इसका प्रभाव क्यों है, लेकिन यदि संभव हो तो समाधान भी बहुत अच्छा होगा।

public class CompressFilter : ActionFilterAttribute 
{ 
    public override void OnResultExecuted(ResultExecutedContext filterContext) 
    { 
     HttpRequestBase request = filterContext.HttpContext.Request; 

     // dont encode images! 
     if (filterContext.Result is ImageResult) 
     { 
      return; 
     } 

     string acceptEncoding = request.Headers["Accept-Encoding"]; 

     if (string.IsNullOrEmpty(acceptEncoding)) return; 

     acceptEncoding = acceptEncoding.ToUpperInvariant(); 

     HttpResponseBase response = filterContext.HttpContext.Response; 

     if (acceptEncoding.Contains("GZIP")) 
     { 
      response.AppendHeader("Content-encoding", "gzip"); 
      response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); 
     } 
     else if (acceptEncoding.Contains("DEFLATE")) 
     { 
      response.AppendHeader("Content-encoding", "deflate"); 
      response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); 
     } 
    } 
} 
+0

+1:

कृपया इस पढ़ें। –

+0

@jordan धन्यवाद! मेरी इच्छा है कि मुझे यह समझने में एक घंटा नहीं लगाया गया कि बेवकूफ [कंप्रेसफिल्टर] विरोधाभासी था। मैं डोनट कैशिंग विफल होने के कारण के रूप में हर संभव चीज की जांच कर रहा था और वास्तव में यह चाहता था कि यह इस उपयोगी फ़िल्टर को इंगित करने के लिए –

+0

+1 समस्या नहीं थी। धन्यवाद! – jao

उत्तर

9

CompressFilter वर्ग के एक बुरा कार्यान्वयन है यही कारण है कि। यह बताते हुए कि आप स्रोत कोड के माध्यम से देखा है Finding Preferred Accept Encoding in C#

मैं अपने ही लिखा है कि इसके बाद के संस्करण लेख पर आधारित AcceptEncoding आज्ञा का पालन करेंगे ::

public class CompressFilter : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     HttpRequestBase request = filterContext.HttpContext.Request; 

     string[] supported = new string[] { "gzip", "deflate" }; 

     IEnumerable<string> preferredOrder = new AcceptList(request.Headers["Accept-Encoding"], supported); 

     string preferred = preferredOrder.FirstOrDefault(); 

     HttpResponseBase response = filterContext.HttpContext.Response; 

     switch (preferred) 
     { 
      case "gzip": 
       response.AppendHeader("Content-Encoding", "gzip"); 
       response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); 
       break; 

      case "deflate": 
       response.AppendHeader("Content-Encoding", "deflate"); 
       response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); 
       break; 

      case "identity": 
      default: 
       break; 
     } 
    } 
} 

public class AcceptList : IEnumerable<string> 
{ 
    Regex parser = new Regex(@"(?<name>[^;,\r\n]+)(?:;q=(?<value>[\d.]+))?", RegexOptions.Compiled); 

    IEnumerable<string> encodings; 

    public AcceptList(string acceptHeaderValue, IEnumerable<string> supportedEncodings) 
    { 
     List<KeyValuePair<string, float>> accepts = new List<KeyValuePair<string, float>>(); 

     if (!string.IsNullOrEmpty(acceptHeaderValue)) 
     { 
      MatchCollection matches = parser.Matches(acceptHeaderValue); 

      var values = from Match v in matches 
         where v.Success 
         select new 
         { 
          Name = v.Groups["name"].Value, 
          Value = v.Groups["value"].Value 
         }; 

      foreach (var value in values) 
      { 
       if (value.Name == "*") 
       { 
        foreach (string encoding in supportedEncodings) 
        { 
         if (!accepts.Where(a => a.Key.ToUpperInvariant() == encoding.ToUpperInvariant()).Any()) 
         { 
          accepts.Add(new KeyValuePair<string, float>(encoding, 1.0f)); 
         } 
        } 

        continue; 
       } 

       float desired = 1.0f; 
       if (!string.IsNullOrEmpty(value.Value)) 
       { 
        float.TryParse(value.Value, out desired); 
       } 

       if (desired == 0.0f) 
       { 
        continue; 
       } 

       accepts.Add(new KeyValuePair<string, float>(value.Name, desired)); 
      } 
     } 

     this.encodings = from a in accepts 
         where supportedEncodings.Where(se => se.ToUpperInvariant() == a.Key.ToUpperInvariant()).Any() || a.Key.ToUpperInvariant() == "IDENTITY" 
         orderby a.Value descending 
         select a.Key; 
    } 

    IEnumerator<string> IEnumerable<string>.GetEnumerator() 
    { 
     return this.encodings.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ((IEnumerable)this.encodings).GetEnumerator(); 
    } 
} 
+0

धन्यवाद।केवल differnece स्वीकार कर रहा है? मेरे पास अभी उनकी तुलना करने का समय नहीं है। thx फिर –

+0

हाँ, बहुत ज्यादा। –

2

मैं OnResultExecuting विधि को ओवरराइड करता हूं। इसे ActionResult को प्रस्तुत करने से पहले कहा जाता है। यह देखने के लिए कि क्लाइंट संपीड़न स्वीकार करता है या नहीं, मैं परिणाम के प्रकार की जांच करता हूं जिसे मैं प्रस्तुत करने की कोशिश कर रहा हूं। यदि यह ViewResult नहीं है, तो मैं किसी भी तरह का संपीड़न लागू नहीं करता हूं।

इसके लिए काम करने के लिए, आपकी कार्रवाइयों को स्पष्ट रूप से या तो देखें() या PartialView() को कॉल करना होगा।

public class CompressOutputAttribute : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     var result = filterContext.Result; 
     if (!(result is ViewResult)) 
      return; 

     HttpRequestBase request = filterContext.HttpContext.Request; 
     string acceptEncoding = request.Headers["Accept-Encoding"]; 
     if (string.IsNullOrEmpty(acceptEncoding)) 
      return; 

     acceptEncoding = acceptEncoding.ToUpperInvariant(); 

     HttpResponseBase response = filterContext.HttpContext.Response; 
     if (acceptEncoding.Contains("GZIP")) 
     {   
      // we want to use gzip 1st 
      response.AppendHeader("Content-encoding", "gzip"); 
      //Add DeflateStream to the pipeline in order to compress response on the fly 
      response.Filter = new GZipStream(response.Filter, CompressionMode.Compress); 
     } 
     else if (acceptEncoding.Contains("DEFLATE")) 
     { 
      //If client accepts deflate, we'll always return compressed content 
      response.AppendHeader("Content-encoding", "deflate"); 
      //Add DeflateStream to the pipeline in order to compress response on the fly 
      response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress); 
     } 
    } 
} 

नियंत्रक के अंदर::

यहाँ CompressOutputAttrtibute कैसा दिखता है

[CompressOutput] 
public class ArticleController : Controller 

    public PartialViewResult MostPopular() 
    { 
     var viewModel = ArticleMostPopularViewModel(); 
     viewModel.Articles = CmsService.GetMostPopularArticles(); 
     return PartialView(viewModel); 
    } 

    public ViewResult Show(int id) 
    { 
     var viewModel = ArticleShowViewModel(); 
     viewModel.Article = CmsService.GetArticle(id); 
     return View(viewModel); 
    } 
} 
+0

+1। मैंने पाया कि OnActionExecuting में संपीड़न लागू करने से समस्या उत्पन्न होती है जब कोई त्रुटि होती है क्योंकि सामग्री-एन्कोडिंग हेडर साफ़ किया जाता है लेकिन फ़िल्टर स्ट्रीम नहीं करता है। –

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