Tüm ASP.NET web sitesi için tarayıcı önbelleğini devre dışı bırak


199

Tüm ASP.NET MVC Web sitesi için tarayıcı önbelleğini devre dışı bırakmak için bir yöntem arıyorum

Aşağıdaki yöntemi buldum:

Response.Cache.SetCacheability(System.Web.HttpCacheability.NoCache);
Response.Cache.SetNoStore();

Ve ayrıca bir meta etiket yöntemi (benim için işe yaramaz, çünkü bazı MVC eylemleri Ajax aracılığıyla bir baş, meta etiket olmadan kısmi HTML / JSON gönderir).

<meta http-equiv="PRAGMA" content="NO-CACHE">

Ancak tüm web sitesi için tarayıcı önbelleğini devre dışı bırakmak için basit bir yöntem arıyorum.


Yanıtlar:


92
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();

Tüm istekler ilk olarak default.aspx üzerinden yönlendirilir - bu yüzden arkada kod girebilirsiniz.


17
Ben Application_BeginRequest () Global.asax.cs içine koymak. Bu default.aspx şey güvenmiyorum ... Başka bir soru: Bu [OutputCache] öznitelikleri üzerinde önceliği var mı?
chris166

5
Sadece Küresel Eylem Filtresi oluşturma ve bu şeyleri bu şekilde koyma fikrini seviyorum. Default.aspx ve Global.asax hakkında endişelenme ihtiyacını ortadan kaldırır.
Keith Adler

13
Bunu Application_BeingRequest içine koymak bazı sorunlara neden olabilir. Resimleriniz .net çalışma zamanı üzerinden yönlendirilirse (güzel URL'ler için joker karakter eşlemesi kullanıyorsanız gerçekleşebilir), tarayıcıda hiçbir görüntü önbelleğe alınmaz. Bu, her sayfa isteği tüm resimleri yeniden indireceğinden GERÇEKTEN sayfa yükleme sürelerinizi yavaşlatabilir.
herbrandson

4
Programlı olarak herhangi bir şey kullanıldığında, bildirilen Özellik her zaman geçersiz kılınır. Başka bir deyişle, OP kodunun kullanılması bildirilen [OutputCache] özniteliğini geçersiz kılar.
Dave Black

Testin nasıl yapılacağı ve önbellek devre dışı bırakmanın gerçekten çalıştığını doğrulayan herhangi bir düşünce var mı?
paaone

366

IActionFilter öğesinden devralan bir sınıf oluşturun.

public 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);
    }
}

Ardından özellikleri gereken yere koyun ...

[NoCache]
[HandleError]
public class AccountController : Controller
{
    [NoCache]
    [Authorize]
    public ActionResult ChangePassword()
    {
        return View();
    }
}

19
HttpContext.Current.Response yerine, HttpContext.Current MVC öncesi HttpContext nesnesini ve filterContext.HttpContext MVC sonrası HttpContextBase öğesini döndürdüğü için muhtemelen filterContext.HttpContext.Response kullanmalısınız. Test edilebilirliği ve tutarlılığı artırır.
mkedobbs

5
IActionFilter, ActionFilterAttribute üzerinde zaten uygulandığından, tekrarlamanız gerekmez.
Andrew Davey

104
ASP.NET MVC'nin geçerli sürümlerinde, önbelleğe almayı önlemek için OutputCacheAttribute'u kullanabilirsiniz: [OutputCache (NoStore = true, Süre = 0, VaryByParam = "None")]
Ashley Tate

9
ASP.NET MVC için güneş altında bu soruyu kabul edilen cevap da dahil olmak üzere her "boşuna kodunu koymak için" çözümünü kullanarak birkaç gün geçirdim işaret etmek istiyorum. Bu cevap - nitelik - işe yaradı. + 1M Temsil edebilsem ...
Tom Kidd

5
En if (filterContext.IsChildAction) return;üste eklemek isteyebilirsiniz - bu, dış eylemin NoCacheöznitelikle süslenmiş bir alt eylem çağırması durumunda 'önbelleğe alınmasını' önler . Başka bir deyişle, NoCacheöznitelik alt eylemleri yürütürlerse diğer eylemlere sızmaz. Ayrıca, sınıf adı, NoCacheAttributeöznitelikler için genel kabul gören adlandırma kuralına uygun olmalıdır .
Jakub Konecki

132

Kendinizi yuvarlamak yerine, sizin için sağlananları kullanın.

Daha önce de belirtildiği gibi, her şey için önbelleğe almayı devre dışı bırakmayın. Örneğin, ASP.NET MVC'de yoğun olarak kullanılan jQuery komut dosyalarının önbelleğe alınması gerekir. Aslında ideal olanlar için yine de bir CDN kullanmalısınız , ama benim açımdan bazı içeriğin önbelleğe alınması gerekiyor.

Ne buldum burada her yerde [OutputCache] serpme yerine en iyi çalışır bir sınıf kullanmaktır:

[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public class NoCacheController  : Controller
{
}

Önbelleğini devre dışı bırakmak istediğiniz tüm denetleyicileriniz, ardından bu denetleyiciden devralın.

NoCacheController sınıfındaki varsayılanları geçersiz kılmanız gerekirse, eylem yönteminizdeki önbellek ayarlarını belirtmeniz yeterlidir; Eylem yönteminizdeki ayarlar öncelikli olur.

[HttpGet]
[OutputCache(NoStore = true, Duration = 60, VaryByParam = "*")]
public ViewResult Index()
{
  ...
}

4
@ Ozziepeeps, yorumunuz doğru değil. Msdn belgeleri tarayıcı önbelleğini tartışır ve basit bir test, bu özniteliğin önbellek kontrolü yanıt başlığını "Cache-Control: public", no-store, max-age = 0 "olarak değiştirir. özniteliğini kullanarak.
Adam Tuliper - MSFT

2
Ayrıca fyi - bu özniteliği ile üç konumu da (sunucu, proxy, istemci) kontrol edebilirsiniz, böylece kesinlikle sunucu önbelleğinin ötesinde kontrol edebilirsiniz. Bazı ek ayrıntılar için bkz. Asp.net/mvc/tutorials/… .
Adam Tuliper - MSFT

1
+1 "NoCacheController sınıfındaki varsayılanları geçersiz kılmanız gerekiyorsa, eylem yönteminizdeki önbellek ayarlarını belirtmeniz yeterlidir; Eylem yönteminizdeki ayarlar öncelik kazanacaktır."
Korayem

2
[System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]Sınıf düzeyinde kullanırsanız , sınıfınızda PartialView'ların bulunamayacağını lütfen unutmayın .
Vivian River

1
OutputCache yöntemi, iki koşul olduğunda IE önbelleğini engellemedi: 1) eylem parametre almadı ve 2) eylem yalnızca Content (someText) yoluyla metin döndürdü. Ben JSON dönmek ve bir parametre almak, IE önbellekleme düzgün yendi.
Kasey Speakman

10

Denetleyiciler (HTML sayfaları) tarafından oluşturulan tüm sayfalar için tarayıcı önbelleğini devre dışı bırakmak, ancak komut dosyaları, stil sayfaları ve resimler gibi kaynaklar için önbelleğe almayı sürdürmek isteyebilirsiniz . MVC4 + gruplama ve küçültme kullanıyorsanız, komut dosyaları ve stil sayfaları için varsayılan önbellek sürelerini korumak isteyeceksiniz (önbellek zamana göre değil, benzersiz bir URL'deki bir değişikliğe göre geçersiz kılınacağı için).

MVC4 + 'da, tüm denetleyiciler arasında tarayıcı önbelleğini devre dışı bırakmak, ancak bir denetleyici tarafından sunulmayan herhangi bir şey için saklamak için şunu ekleyin FilterConfig.RegisterGlobalFilters:

filters.Add(new DisableCache());

Aşağıdaki DisableCachegibi tanımlayın :

class DisableCache : ActionFilterAttribute
{
    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    }
}

Oturumu kapattıktan sonra geri düğmesine basmak sayfayı görüntülediğinden maalesef bu işe yaramıyor gibi görünüyor.
ʙᴀᴋᴇʀ ʙᴀᴋᴇʀ

6

Bu cevabın soru ile ilgili% 100 olmadığını biliyorum, ama birisine yardımcı olabilir.

Tüm ASP.NET MVC Web sitesi için tarayıcı önbelleğini devre dışı bırakmak istiyorsanız , ancak yalnızca bu geçici olarak yapmak istiyorsanız, tarayıcınızdaki önbelleği devre dışı bırakmak daha iyidir.

İşte Chrome'da bir ekran görüntüsü


Bu tam olarak aradığım şeydi ... dev sırasında, bir .js dosyasını değiştirirsem, küçük sorun giderme / yenileme / test döngüleri yapma konusunda sorun yaşadığımda hemen ortaya çıkması büyük bir acıdır. Bu mükemmel, teşekkürler! Sadece müşteri tarafı hata ayıklama hayatı çok daha kolay
jleach

2

Önceki tüm cevapları uyguladım ve hala düzgün çalışmayan bir görüşüm vardı.

Sorun yaşadığım görünümün adı 'Yeni' olarak adlandırıldı. Görünüşe göre bu Internet Explorer tarayıcısını karıştırdı.

Görünüm adını (denetleyicide) farklı bir adla değiştirdikten sonra ('Recent5' i seçtim), yukarıdaki çözümler çalışmaya başladı.


0

Global.asax dosyasında aşağıdaki kodu deneyebilirsiniz.

protected void Application_BeginRequest()
    {
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.Cache.SetExpires(DateTime.UtcNow.AddHours(-1));
        Response.Cache.SetNoStore();
    }

-1

UI

<%@ OutPutCache Location="None"%>
<%
    Response.Buffer = true;
    Response.Expires = -1;
    Response.ExpiresAbsolute = System.DateTime.Now.AddSeconds(-1);
    Response.CacheControl = "no-cache";
%>

Arka fon

Context.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
Response.Expires = -1;          
Response.Cache.SetNoStore();

1
teknik olarak doğru olsa bile açıklayıcı
nesire ihtiyacı var
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.