2012-02-09 15 views
11

मैं एक कार्य विधि है कि मैं कैश करने के लिए करना चाहते हैं हिट:OutputCache गलत भेज रहा है हैडर वैरी जब कॉल कैश

[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="index")] 
public ActionResult Index() 
{ 
    return View(); 
} 
इस दृष्टिकोण के साथ

:

public override string GetVaryByCustomString(HttpContext context, string custom) 
{ 
    context.Response.Cache.SetOmitVaryStar(true); 
    context.Response.Cache.VaryByHeaders["Cookie"] = true; 

    if (User.Identity.IsAuthenticated) 
    { 
     Debug.Print("Authenticated"); 
     context.Response.Cache.SetNoServerCaching(); 
     context.Response.Cache.SetCacheability(HttpCacheability.Private); 
     return null; 
    } 
    else 
    { 
     Debug.Print("Non authenticated"); 
     return custom; 
    } 
} 

विचार keep a cached version of the page for non-authenticated users, but avoid caching for authenticated ones गया था।

मैंने सोचा कि यह हमेशा Vary:Cookie HTTP शीर्षलेख लौटाएगा, लेकिन ऐसा नहीं है। पहले HTTP में फ़िडलर के साथ एक परीक्षण कर रहा है और दो बार एक ही अनुरोध पत्र जारी करने, कॉल यह अच्छा है:

HTTP/1.1 200 OK 
Cache-Control: public, max-age=300 
Content-Type: text/html; charset=utf-8 
Expires: Thu, 09 Feb 2012 10:53:36 GMT 
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT 
Vary: Cookie 
Server: Microsoft-IIS/7.5 
X-AspNetMvc-Version: 3.0 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Thu, 09 Feb 2012 10:48:37 GMT 
Content-Length: 441 

लेकिन दूसरा एक में, यह हैडर अधिलेखित कर देता है:

HTTP/1.1 200 OK 
Cache-Control: public, max-age=297 
Content-Type: text/html; charset=utf-8 
Expires: Thu, 09 Feb 2012 10:53:36 GMT 
Last-Modified: Thu, 09 Feb 2012 10:48:36 GMT 
Vary: * 
Server: Microsoft-IIS/7.5 
X-AspNetMvc-Version: 3.0 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Thu, 09 Feb 2012 10:48:39 GMT 
Content-Length: 441 

तो, के रूप में जहां तक ​​मुझे पता है, ब्राउज़र सार्वजनिक होने पर भी अनुरोध को कैश नहीं करेंगे, क्योंकि Vary:* का अर्थ है कि अनुरोध उन पैरामीटर के साथ जेनरेट किया गया है जो यूआरएल में नहीं हैं और न ही HTTP हेडर में हैं। क्या इसे ठीक करने का कोई तरीका है?

सम्मान।

अद्यतन:

HTTP/1.1 200 OK 
Cache-Control: private, max-age=300 
Content-Type: text/html; charset=utf-8 
Expires: Thu, 09 Feb 2012 12:43:14 GMT 
Last-Modified: Thu, 09 Feb 2012 12:38:14 GMT 
Server: Microsoft-IIS/7.5 
X-AspNetMvc-Version: 3.0 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Thu, 09 Feb 2012 12:38:14 GMT 
Content-Length: 443 

लेकिन दूसरा एक:

इसी प्रकार, जब मैं दो समान प्रमाणीकृत अनुरोध भेजने, पहली कॉल private संशोधक, लेकिन नहीं Vary हैडर हो जाता है एक ही प्रतिक्रिया प्राप्त होती है कि एक गैर-प्रमाणीकृत अनुरोध:

HTTP/1.1 200 OK 
Cache-Control: public, max-age=298 
Content-Type: text/html; charset=utf-8 
Expires: Thu, 09 Feb 2012 12:44:32 GMT 
Last-Modified: Thu, 09 Feb 2012 12:39:32 GMT 
Vary: * 
Server: Microsoft-IIS/7.5 
X-AspNetMvc-Version: 3.0 
X-AspNet-Version: 4.0.30319 
X-Powered-By: ASP.NET 
Date: Thu, 09 Feb 2012 12:39:33 GMT 
Content-Length: 443 

मैंने test project showing the issue अपलोड किया है, तो हो सकता है कि आप इसे आज़माएं।

कृपया ध्यान रखें कि IHttpModule है जो अनुरोध के रूप में प्रमाणित करता है या अनुरोध के आधार पर अनुरोध नहीं करता है, यह एक "असली जीवन" दृष्टिकोण नहीं है, यह केवल परीक्षण उद्देश्यों के लिए है।

परियोजना के लिए एक लिंक, एक कड़ी है कि आप में लॉग करता है, और एक अन्य लिंक है कि आप लॉग बाहर के साथ ही एक वेब पेज में शामिल हैं:

  • लॉगिन: घर के लिए एक HTTP 302 पुनर्निर्देशन में एक कुकी भेजता है पेज फिर से।
  • लॉगऑट: HTTP 302 में होम पेज पर फिर से समाप्त होने पर एक कालबाह्य कुकी भेजता है।

उम्मीद/आदर्श व्यवहार होगा:

  1. उपयोगकर्ता पहुँच सूचकांक, और सर्वर से पृष्ठ मिलता है। पेज शो "ए" दिखाता है।
  2. उपयोगकर्ता पहुंच सूचकांक फिर से, और ब्राउज़र कैश्ड संस्करण दिखाता है। पृष्ठ दिनांक "ए" दिखाता है।
  3. स्वच्छ ब्राउज़र कैश।
  4. उपयोगकर्ता पहुंच सूचकांक फिर से, और ब्राउज़र सर्वर कैश्ड संस्करण दिखाता है। पेज शो "ए" दिखाता है।
  5. उपयोगकर्ता क्लिक लॉगिन, और ब्रोसर को एक नया पृष्ठ मिलता है, जो दिनांक "बी" दिखाता है।
  6. उपयोगकर्ता क्लिक लॉगआउट, और ब्राउज़र को सर्वर कैश पृष्ठ मिलता है। पृष्ठ फिर से "ए" दिखाता है।

लेकिन इस व्यवहार अब तक है:

  1. उपयोगकर्ता पहुँच सूचकांक, और सर्वर से पृष्ठ मिलता है। पेज शो "ए" दिखाता है।
  2. उपयोगकर्ता पहुंच सूचकांक फिर से, और ब्राउज़र कैश्ड संस्करण दिखाता है। पृष्ठ दिनांक "ए" दिखाता है।
  3. स्वच्छ ब्राउज़र कैश।
  4. उपयोगकर्ता पहुंच सूचकांक फिर से, और ब्राउज़र सर्वर कैश्ड संस्करण दिखाता है। पेज शो "ए" दिखाता है।
  5. उपयोगकर्ता क्लिक लॉगिन, और ब्रोसर को एक नया पृष्ठ मिलता है, जो दिनांक "बी" दिखाता है।
  6. उपयोगकर्ता क्लिक लॉगआउट, और ब्राउज़र सर्वर कैश किए गए पृष्ठ को प्राप्त करना चाहिए, लेकिन यह नहीं है। पृष्ठ ब्राउज़र कैश से फिर से "बी" दिनांक दिखाता है। ऐसा इसलिए है क्योंकि प्रमाणीकृत प्रतिक्रिया में Vary शीर्षलेख की कमी।

मैं अगर मैं कुछ कैशिंग के बारे में गलत है, सिर्फ कुछ विस्तार से लापता या OutputCache बहुत अच्छी तरह से काम नहीं करता है पता नहीं है, लेकिन मैं किसी भी मार्गदर्शन की सराहना करेंगे।

चीयर्स।

अद्यतन 2:

  1. ब्राउज़रों और proxys पेज के "सार्वजनिक" संस्करण को कैश करने की अनुमति दें:

    मेरे इरादा करने के लिए HTTP कैश अर्थ विज्ञान का प्रयोग है।

  2. ब्राउज़र को अपने उपयोगकर्ता के लिए पृष्ठ के "प्रमाणीकृत" संस्करण को कैश करने की अनुमति दें।

अगर मैं OutputCache घोषणा बदलने केवल सर्वर पर कैशिंग करते हैं और नीचे की ओर है और ग्राहक कैशिंग को रोकने के लिए:

[OutputCache(Duration=60*5, Location=OutputCacheLocation.Server, VaryByCustom="index")] 

यह उम्मीद है, लेकिन नीचे की ओर है और ग्राहक कैश रोका जाता है के रूप में, बर्ताव करता है और वह वही नहीं है जो मैं चाहता हूं।

+1

क्या होता है यदि आप विधि के आउटपुट कैश विशेषता पर अन्य VaryBy गुण भी सेट करते हैं? – bzlm

+0

मैंने VaryByHeader = "कुकी" जोड़ा है, और यह अभी भी होता है, दूसरी कॉल Vary = * हो जाती है। – vtortola

+0

यदि आप [लिंक किए गए प्रश्न से जुड़े दृष्टिकोण] का प्रयास करते हैं तो क्या होगा (http://visitmix.com/writings/using-varybycustom-with-outputcache-in-asp-net-mvc-to-support-caching-for- लॉग-इन-यूजर्स) के रूप में, अलग-अलग-कुकी के बिना या 'GetVaryByCustom' विधि के अंदर प्रतिक्रिया शीर्षलेख संशोधित कर रहा है? (तकनीकी रूप से, आपको केवल अज्ञात उपयोगकर्ताओं के लिए कैशिंग प्राप्त करने के लिए अलग-अलग कुकी की आवश्यकता नहीं है।) – bzlm

उत्तर

4

मुझे नहीं लगता कि [OutputCache] विशेषता आप क्या चाहते हैं, VaryByCustom विधि मूल रूप से कह रहा है कि मैं इन मापदंडों के आधार पर अलग-अलग संस्करणों कैश करने के लिए चाहते हैं, यह वास्तव में के लिए एक विकल्प कैशे न करें नहीं है करते हैं और विशेषता में कोड का अधिकांश भाग सर्वर आधारित कैशिंग के आसपास बनाया गया है।

public override string GetVaryByCustomString(HttpContext context, string custom) 
{ 
    if(custom == "user") return "User:" + context.Request.User.Identity.Name; 

    return base.GetVaryByCustomString(context, custom); 
} 

और फिर VaryByCustom में उपयोगकर्ता शाब्दिक का उपयोग करें:

कस्टम कैशिंग के लिए MSDN पर प्रलेखन इंगित करने के लिए आप प्रमाणीकरण राज्य के आधार पर अलग-अलग हो पर के लिए एक स्ट्रिंग वापस जाने के लिए की जरूरत है लगता है कहा जा रहा है :

[OutputCache(Duration=60*5, Location=OutputCacheLocation.Any, VaryByCustom="user")] 
public ActionResult Index() 
{ 
    return View(); 
} 

तो मूल रूप से यह एक कैश गुमनाम लिए बनाया जा रहा में परिणाम होगा (यह मानते हुए गुमनाम पहचान रिक्त स्ट्रिंग या कुछ और है) और पर हर उपयोगकर्ता सर्वर, और एक Vary: * क्लाइंट को भेजा गया मेरा मानना ​​है। स्पष्ट रूप से आदर्श नहीं है कि आप क्या खोज रहे हैं।

यदि आप वास्तव में HTTP कैशिंग का उपयोग करके अनधिकृत संस्करण को कैश करना चाहते हैं तो मैं OutputCacheAttribute का उपयोग न करने और कुछ और कस्टम का उपयोग करने की अनुशंसा करता हूं।

आप आसानी से बस अपने स्वयं के कस्टम में लिख सकता है कि आप अपने GetVaryByCustomString कार्यान्वयन के लिए राशि की तरह कुछ गुण (यह सिर्फ कुछ छद्म कोड है, इस से भी अधिक की आवश्यकता होगी):

public class HttpCacheUnauthenticatedAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuted(ActionExecutedContext filterContext) 
    { 
     if(!filterContext.HttpContext.Request.IsAuthenticated) { 
      //TODO: set unauthenticated caching values and vary here 
     } 
    } 
} 

और फिर अपनी कार्रवाई को टैग इसके साथ विधि:

[HttpCacheUnauthenticated] 
public ActionResult Index() 
{ 
    return View(); 
} 
+0

आउटपुट कैश के साथ दृष्टिकोण पहले कॉल में अपेक्षित के रूप में काम कर रहा है, यह केवल आउटपुट कैश में कॉल "कैश हिट" होने पर गलत कॉलरी हेडर को बाद में कॉल में वापस कर रहा है। बस इतना ही। कार्यक्षमता प्रदान की जाती है, लेकिन उम्मीद के अनुसार काम नहीं कर रही है। अपने स्वयं के आउटपुट कैश एक्शन फ़िल्टर को कार्यान्वित करें कुछ भी हल नहीं करेगा। समस्या आउटपुट कैश एट्रिब्यूट नहीं है, लेकिन आउट आउट कैशिंग एपीआई पीछे है। – vtortola

+0

@ vtortola Thats मुझे लगता है कि आपको एपीआई को बाईपास करना चाहिए और हेडर लिखना चाहिए। आप केवल HTTP कैशिंग की तलाश कर रहे हैं, सर्वर साइड कैशिंग सही नहीं है? जैसे मैंने कहा कि आउटपुट कैश विशेषता किसी भी परिदृश्य के लिए डिज़ाइन नहीं की गई है जिसमें इसकी सामग्री प्रतिक्रिया पर कैश नहीं की जाती है। –

+0

नहीं, मैं दोनों की तलाश में हूं: डी ध्यान से पढ़ें "अपेक्षित/आदर्श व्यवहार होगा:" खंड। चीयर्स। – vtortola

0

को web.config में करने की कोशिश की मैं एक कस्टम कैश प्रदाता का उपयोग कर रहा है और इस मामले में इसके लिए एक सरल उपाय है। BeginRequest पर, उपयोगकर्ता प्रमाणीकरण स्थिति के आधार पर, हम एक संदर्भ जानकारी सेट कैश नहीं चलाने के लिए:

HttpContext.Current.Items["NoCache"] = "1"; 

और फिर हमारे GetVaryBy पद्धति पर हम अशक्त वापसी अगर यह जानकारी सेट है:

public override string GetVaryByCustomString(HttpContext context, string custom) 
{ 
    if (HttpContext.Current.Items["NoCache"] != null) 
     return null; 

    // remaining code here 
} 

और उसके बाद कैश विधियों पर, हम इसका परीक्षण कर सकते हैं। उदाहरण के लिए:

public override object Add(string key, object entry, DateTime utcExpiry) 
{ 
    if (HttpContext.Current.Items["NoCache"] != null) 
     return null; 

    // remaining code here 
} 
संबंधित मुद्दे