एक विशेषता का उपयोग करके विशिष्ट कार्यों के लिए ASP.NET MVC में कैशिंग को रोकें


196

मेरे पास ASP.NET MVC 3 अनुप्रयोग है। यह एप्लिकेशन jQuery के माध्यम से रिकॉर्ड का अनुरोध करता है। jQuery एक नियंत्रक क्रिया को कॉल करता है जो JSON प्रारूप में परिणाम देता है। मैं यह साबित नहीं कर पाया हूं, लेकिन मुझे चिंता है कि मेरा डेटा कैश हो सकता है।

मैं केवल यह चाहता हूं कि कैशिंग को विशिष्ट कार्यों के लिए लागू किया जाए, सभी कार्यों के लिए नहीं।

क्या कोई विशेषता है जो मैं यह सुनिश्चित करने के लिए कार्रवाई कर सकता हूं कि डेटा कैश न हो? यदि नहीं, तो मैं कैसे सुनिश्चित करूं कि ब्राउज़र को कैश्ड सेट के बजाय हर बार रिकॉर्ड का एक नया सेट मिले?


1
यदि आप अनुमान लगा रहे हैं कि कुछ कैश किया जा रहा है, तो मेरा सुझाव है कि आप यहाँ कैश कंट्रोल मैकेनिज्म पर पढ़ें: w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9

जवाबों:


304

यह सुनिश्चित करने के लिए कि JQuery आपके ajax तरीकों पर परिणामों को कैशिंग नहीं कर रहा है, निम्नलिखित डालें:

$.ajax({
    cache: false
    //rest of your ajax setup
});

या एमवीसी में कैशिंग को रोकने के लिए, हमने अपनी विशेषता बनाई, आप भी ऐसा कर सकते हैं। यहाँ हमारा कोड है:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
        filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        filterContext.HttpContext.Response.Cache.SetNoStore();

        base.OnResultExecuting(filterContext);
    }
}

तो बस अपने नियंत्रक के साथ सजाने [NoCache]। या यह सब करने के लिए आप बस बेस क्लास की उस विशेषता को रख सकते हैं जो आप अपने नियंत्रकों से (यदि आपके पास एक है) जैसे कि हमारे यहां है:

[NoCache]
public class ControllerBase : Controller, IControllerBase

आप इस विशेषता के साथ कुछ कार्यों को भी सजा सकते हैं यदि आपको पूरे नियंत्रक को सजाने के बजाय उन्हें गैर-उपलब्ध होने की आवश्यकता है।

यदि आपकी क्लास या क्रिया NoCacheतब नहीं हुई थी जब आपके ब्राउज़र में इसे प्रस्तुत किया गया था और आप यह जाँचना चाहते हैं कि यह काम कर रहा है, तो याद रखें कि परिवर्तनों को संकलित करने के बाद आपको अपने ब्राउज़र में "हार्ड रिफ्रेश" (Ctrl + F5) करने की आवश्यकता है। जब तक आप ऐसा नहीं करते हैं, तब तक आपका ब्राउज़र पुराने कैश्ड संस्करण को रखेगा, और इसे "सामान्य ताज़ा" (F5) के साथ ताज़ा नहीं करेगा।


1
मैंने उपरोक्त समाधान में सब कुछ करने की कोशिश की और यह मेरे लिए काम नहीं करता है।
ओबी वान

9
यह मेरी समझ (और मैं कोई jQuery का विशेषज्ञ नहीं हूँ) कि कैश: झूठी केवल क्वेरी को स्ट्रिंग करता है jQuery के एक बदलते मूल्य को ब्राउज़र में "ट्रिक" करने के लिए अनुरोध करने में सोचता है कि अनुरोध कुछ और है। सिद्धांत रूप में, इसका अर्थ है कि ब्राउज़र अभी भी परिणामों को कैश करेगा, बस कैश्ड परिणामों का उपयोग नहीं करेगा। प्रतिक्रिया हेडर के माध्यम से कैशिंग को अक्षम करने के लिए क्लाइंट पर अधिक कुशल होना चाहिए।
जोश

2
केवल नियंत्रक स्तर पर काम किया गया है और कार्रवाई स्तर पर नहीं।
रमेश

3
मैं आधिकारिक ASP.NET पैकेज में इस तरह की विशेषता को शामिल करना चाहूंगा :-)
usr-local-

1
@ Frédéric, आपके द्वारा बताए गए चश्मे के अनुभाग का कहना है कि कैश नो-स्टोर कंटेंट को कैश नहीं कर सकता है: "नो-स्टोर" प्रतिक्रिया निर्देश इंगित करता है कि कैश अनुरोध या प्रतिक्रिया के किसी भी हिस्से को स्टोर नहीं करना चाहिए।
kristianp

258

कैशिंग को रोकने के लिए आप अंतर्निहित कैश विशेषता का उपयोग कर सकते हैं।

.Net फ्रेमवर्क के लिए: [OutputCache(NoStore = true, Duration = 0)]

.Net कोर के लिए: [ResponseCache(NoStore = true, Duration = 0)]

ध्यान रखें कि कैशिंग को अक्षम करने के लिए ब्राउज़र को मजबूर करना असंभव है। आप जो सबसे अच्छा कर सकते हैं, वह सुझाव प्रदान करें जो कि अधिकांश ब्राउज़र सम्मान करेंगे, आमतौर पर हेडर या मेटा टैग के रूप में। यह डेकोरेटर विशेषता सर्वर कैशिंग को अक्षम कर देगा और इस शीर्षक को भी जोड़ देगा Cache-Control: public, no-store, max-age=0:। यह मेटा टैग नहीं जोड़ता है। यदि वांछित है, तो उन्हें मैन्युअल रूप से दृश्य में जोड़ा जा सकता है।

इसके अतिरिक्त, JQuery और अन्य क्लाइंट फ्रेमवर्क ब्राउज़र में ट्रिक करने का प्रयास करेंगे, यह टाइमस्टैम्प या GUID की तरह url में सामान जोड़कर किसी संसाधन के कैश्ड संस्करण का उपयोग नहीं करेगा। यह ब्राउज़र को फिर से संसाधन के लिए पूछने में प्रभावी है लेकिन वास्तव में कैशिंग को नहीं रोकता है।

एक अंतिम नोट पर। आपको पता होना चाहिए कि सर्वर और क्लाइंट के बीच संसाधन भी कैश किए जा सकते हैं। आईएसपी के, प्रॉक्सी और अन्य नेटवर्क उपकरण भी संसाधनों को कैश करते हैं और वे अक्सर वास्तविक संसाधन को देखे बिना आंतरिक नियमों का उपयोग करते हैं। इन के बारे में आप बहुत कुछ नहीं कर सकते। अच्छी खबर यह है कि वे आम तौर पर सेकंड या मिनट की तरह कम समय के फ्रेम के लिए कैश करते हैं।


3
मेरा मानना ​​है कि यह प्रश्न को पूरी तरह से संबोधित नहीं करता है। यह ASP.NET कैशिंग को अक्षम करता है, लेकिन ब्राउज़र कैशिंग को नहीं।
रोजडी कासिम

22
कैशिंग को अक्षम करने के लिए ब्राउज़र को मजबूर करना असंभव है। आप जो सबसे अच्छा कर सकते हैं, वह सुझाव प्रदान करें जो कि अधिकांश ब्राउज़र सम्मान करेंगे, आमतौर पर हेडर या मेटा टैग के रूप में। यह डेकोरेटर विशेषता .NET सर्वर कैशिंग को अक्षम करेगा और हेडर भी जोड़ेगा Cache-Control:public, no-store, max-age=0। यह मेटा टैग नहीं जोड़ता है। यदि वांछित है, तो उन्हें मैन्युअल रूप से दृश्य में जोड़ा जा सकता है।
जगुआर

1
मैं समझ सकता हूं कि आप क्यों उपयोग करेंगे NoStore = trueऔर Duration = 0(जो मैंने सफलतापूर्वक उपयोग किया है, धन्यवाद), लेकिन क्या अतिरिक्त प्रभाव होगा VaryByParam = "None"क्योंकि अन्य दो विकल्प पैरामीटर की परवाह किए बिना सभी अनुरोधों को प्रभावित करते हैं?
कोडिंग हुआ

मुझे नहीं लगता कि एमवीसी में इसकी आवश्यकता है, मैं सिर्फ स्पष्ट था। मुझे याद है कि ASP.NET वेब रूपों और उपयोगकर्ता नियंत्रणों में, या तो यह विशेषता या VaryByControl विशेषता आवश्यक है।
जगुआर

1
ASP.NET के लिए कोर का उपयोग करें: '[ResponseCache (NoStore = true, Duration = 0)]'
जेफ

48

जो तुम्हे चाहिए वो है:

[OutputCache(Duration=0)]
public JsonResult MyAction(

या, यदि आप इसे संपूर्ण नियंत्रक के लिए अक्षम करना चाहते हैं:

[OutputCache(Duration=0)]
public class MyController

यहां टिप्पणियों में बहस के बावजूद, यह ब्राउज़र कैशिंग को अक्षम करने के लिए पर्याप्त है - यह ASP.Net का कारण प्रतिक्रिया हेडर का उत्सर्जन करता है जो ब्राउज़र को यह बताता है कि दस्तावेज़ तुरंत समाप्त हो रहा है:

OutputCache अवधि = 0 प्रतिक्रिया शीर्षलेख: अधिकतम-आयु = 0, s-maxage = 0


6
IE8 अभी भी पृष्ठ के कैश्ड संस्करण को प्रस्तुत करता है जब एक कंट्रोलर एक्शन पर केवल Duration = 0 का उपयोग करके बैक बटन पर क्लिक किया जाता है। NoStore = true के साथ Duration = 0 का उपयोग करना (देखें Jared का उत्तर) ने मेरे मामले में व्यवहार को ठीक कर दिया।
कीथ केटरर

3
यह सेटिंग के Cache-Controlलिए कुछ उत्सुक व्यवहार हैpublic
ta.speot.is

max-age=0कभी 'कैश अक्षम' का मतलब नहीं है। इसका मतलब केवल यह है कि प्रतिक्रिया सामग्री को तुरंत बासी माना जाता है , लेकिन कैश को इसे कैश करने की अनुमति है। ब्राउज़रों को उपयोग करने से पहले कैश्ड बासी सामग्री की ताजगी को मान्य करना चाहिए, लेकिन जब तक अतिरिक्त निर्देश must-revalidateनिर्दिष्ट नहीं किया जाता तब तक यह अनिवार्य नहीं है।
Frédéric

14

कंट्रोलर एक्शन में हेडर को निम्न पंक्तियों में जोड़ें

    public ActionResult Create(string PositionID)
    {
        Response.AppendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
        Response.AppendHeader("Pragma", "no-cache"); // HTTP 1.0.
        Response.AppendHeader("Expires", "0"); // Proxies.

5

यहाँ NoCacheक्रिस मॉसचिनी के उत्तर की जानकारी का उपयोग करके सरलीकृत माटीटोमो द्वारा प्रस्तावित विशेषता है:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public sealed class NoCacheAttribute : OutputCacheAttribute
{
    public NoCacheAttribute()
    {
        this.Duration = 0;
    }
}

किसी कारण से MVC 3 आपको केवल 0. की अवधि निर्धारित नहीं करने देता है। आपको इन एनोटेशन को जोड़ना होगा ... वर्कअराउंड के लिए धन्यवाद!
१६:१५ पर माईकओवर

max-age=0कभी 'कैश अक्षम' का मतलब नहीं है। इसका मतलब केवल यह है कि प्रतिक्रिया सामग्री को तुरंत बासी माना जाता है , लेकिन कैश को इसे कैश करने की अनुमति है। ब्राउज़रों को उपयोग करने से पहले कैश्ड बासी सामग्री की ताजगी को मान्य करना चाहिए, लेकिन जब तक अतिरिक्त निर्देश must-revalidateनिर्दिष्ट नहीं किया जाता तब तक यह अनिवार्य नहीं है।
Frédéric

पूर्णता के लिए, न्यूनतम और अधिक उपयुक्त निर्देश है no-cache, जो अभी भी कैशिंग लेकिन किसी भी उपयोग से पहले मूल सर्वर पर पुनर्वितरित करने की अनुमति देता है। यहां तक ​​कि अमान्य कैशिंग से बचने के लिए आपको no-storeसाथ जोड़ना होगा no-cache। ( no-storeअकेले स्पष्ट रूप से गलत है, क्योंकि अस्थिर कैश को सामग्री के रूप में चिह्नित करने की अनुमति है no-store।)
Frédéric

4

MVC6 ( DNX ) के लिए, नहीं हैSystem.Web.OutputCacheAttribute

नोट: जब आप सेट करते हैं तो NoStoreअवधि पैरामीटर पर विचार नहीं किया जाता है। पहले पंजीकरण के लिए प्रारंभिक अवधि निर्धारित करना और कस्टम विशेषताओं के साथ इसे ओवरराइड करना संभव है।

लेकिन हमारे पास है Microsoft.AspNet.Mvc.Filters.ResponseCacheFilter

 public void ConfigureServices(IServiceCollection services)
        ...
        services.AddMvc(config=>
        {
            config.Filters.Add(
                 new ResponseCacheFilter(
                    new CacheProfile() { 
                      NoStore=true
                     }));
        }
        ...
       )

एक कस्टम विशेषता के साथ प्रारंभिक फ़िल्टर को ओवरराइड करना संभव है

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public sealed class NoCacheAttribute : ActionFilterAttribute
    {
        public override void OnResultExecuting(ResultExecutingContext filterContext)
        {
            var filter=filterContext.Filters.Where(t => t.GetType() == typeof(ResponseCacheFilter)).FirstOrDefault();
            if (filter != null)
            {
                ResponseCacheFilter f = (ResponseCacheFilter)filter;
                f.NoStore = true;
                //f.Duration = 0;
            }

            base.OnResultExecuting(filterContext);
        }
    }

यहाँ एक उपयोग मामला है

    [NoCache]
    [HttpGet]
    public JsonResult Get()
    {            
        return Json(new DateTime());
    }

1

MVC में आउटपुट कैशिंग

[OutputCache (NoStore = true, अवधि = 0, स्थान = "कोई नहीं", VaryByParam = "*")]

या
[OutputCache (NoStore = true, Duration = 0, VaryByParam = "कोई नहीं")]


पहले से ही इसका उपयोग करने वाले कई उत्तरों पर अन्य टिप्पणियां ( 1 , 2 , 3 ) देखें । आपकी दूसरी पंक्ति गलत है और कुछ ब्राउज़रों के साथ समस्याओं को जन्म देगी।
फ्रेडेरिक

1

ब्राउज़र कैशिंग ( इंटरनेट एक्सप्लोरर 11 सहित ) को रोकने के लिए Asp.Net MVC कोर के लिए सही विशेषता मान है:

[ResponseCache(Location = ResponseCacheLocation.None, NoStore = true)]

जैसा कि Microsoft प्रलेखन में वर्णित है:

ASP.NET कोर में प्रतिक्रिया कैशिंग - NoStore और Location.None


0

ASP.NET MVC 5 समाधान:

  1. एक केंद्रीय स्थान पर रोकथाम कोड कैशिंग: App_Start/FilterConfig.csकी RegisterGlobalFiltersविधि:
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            // ...
            filters.Add(new OutputCacheAttribute
            {
                NoStore = true,
                Duration = 0,
                VaryByParam = "*",
                Location = System.Web.UI.OutputCacheLocation.None
            });
        }
    }
  1. एक बार जब आपके पास यह हो जाता है कि मेरी समझ में यह है कि आप एक अलग OutputCacheनिर्देश Controllerया Viewस्तर पर लागू करके वैश्विक फ़िल्टर को ओवरराइड कर सकते हैं । नियमित नियंत्रक के लिए
[OutputCache(NoStore = true, Duration = 0, Location=System.Web.UI.ResponseCacheLocation.None, VaryByParam = "*")]

या अगर यह एक ApiControllerऐसा होगा

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, Location = System.Web.UI.OutputCacheLocation.None, VaryByParam = "*")]
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.