Vô hiệu hóa bộ đệm của trình duyệt cho toàn bộ trang web ASP.NET


199

Tôi đang tìm kiếm một phương pháp để vô hiệu hóa bộ đệm của trình duyệt cho toàn bộ trang web ASP.NET MVC

Tôi tìm thấy phương pháp sau:

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

Và cũng là một phương thức thẻ meta (nó sẽ không hoạt động đối với tôi, vì một số hành động MVC gửi một phần HTML / JSON thông qua Ajax, không có thẻ meta, đầu).

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

Nhưng tôi đang tìm kiếm một phương pháp đơn giản để vô hiệu hóa bộ đệm của trình duyệt cho toàn bộ trang web.


Câu trả lời:


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ất cả các yêu cầu được chuyển qua default.aspx trước tiên - vì vậy, giả sử bạn chỉ có thể bật mã phía sau đó.


17
Tôi sẽ đặt nó vào Global.asax.cs trong Application_BeginRequest (). Tôi không tin tưởng điều mặc định này.aspx ... Một câu hỏi khác: điều này có được ưu tiên hơn các thuộc tính [OutputCache] không?
chris166

5
Tôi thích ý tưởng đơn giản là tạo Bộ lọc hành động toàn cầu và đặt công cụ này theo cách đó. Phủ nhận sự cần thiết phải lo lắng về Default.aspx và Global.asax.
Keith Adler

13
Đưa cái này vào Application_ByingRequest có thể gây ra một số vấn đề. Nếu hình ảnh của bạn được định tuyến thông qua thời gian chạy .net (điều này có thể xảy ra nếu bạn đang sử dụng ánh xạ ký tự đại diện cho các url đẹp) thì sẽ không có hình ảnh nào được lưu trong bộ nhớ cache trên trình duyệt. Điều này có thể THỰC SỰ làm chậm thời gian tải trang của bạn vì mỗi yêu cầu trang sẽ tải xuống lại tất cả hình ảnh.
Herbrandson

4
Sử dụng bất cứ thứ gì theo chương trình sẽ luôn ghi đè bất kỳ Thuộc tính được khai báo nào. Nói cách khác, sử dụng mã của OP sẽ ghi đè bất kỳ thuộc tính [OutputCache] đã khai báo nào.
Dave Black

Bạn có suy nghĩ gì về cách hút thử nghiệm và xác minh rằng bộ đệm ẩn thực sự hoạt động không?
paaone

366

Tạo một lớp kế thừa từ IActionFilter.

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

Sau đó đặt các thuộc tính khi cần ...

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

19
Thay vì HTTPContext.Cản.Response, có lẽ bạn nên sử dụng bộ lọcContext.HttpContext.Response kể từ httpContext.C hiện trả về đối tượng HttpContext tiền MVC và bộ lọcContext.HttpContext trả về httpContextBase sau MVC. Nó làm tăng khả năng kiểm tra và tính nhất quán.
mkedobbs

5
IActionFilter đã được triển khai trên ActionFilterAttribution, vì vậy bạn không cần lặp lại nó.
Andrew Davey

104
Trong các phiên bản hiện tại của ASP.NET MVC, bạn chỉ cần sử dụng OutputCacheAttribution để ngăn chặn bộ đệm ẩn: [OutputCache (NoStore = true, Thời gian = 0, VaryByParam = "Không")]
Ashley Tate

9
Tôi muốn chỉ ra rằng tôi chỉ mất vài ngày để sử dụng mọi giải pháp "đặt mã này vào mã của bạn để dừng bộ đệm" dưới ánh mặt trời cho ASP.NET MVC, bao gồm cả câu trả lời được chấp nhận cho câu hỏi này, nhưng không có kết quả. Câu trả lời này - thuộc tính - đã làm việc. + 1 triệu Rep nếu tôi có thể ...
Tom Kidd

5
Bạn có thể muốn thêm if (filterContext.IsChildAction) return;ở trên cùng - điều này sẽ ngăn hành động bên ngoài là 'không được lưu trong bộ nhớ cache' nếu nó gọi một hành động con được trang trí bằng NoCachethuộc tính. Nói cách khác, NoCachethuộc tính sẽ không bị rò rỉ sang các hành động khác nếu chúng thực hiện các hành động con. Ngoài ra, tên lớp phải NoCacheAttributetuân theo quy ước đặt tên được chấp nhận chung cho các thuộc tính.
Jakub Konecki

132

Thay vì tự lăn, chỉ cần sử dụng những gì cung cấp cho bạn.

Như đã đề cập trước đó, không tắt bộ nhớ đệm cho mọi thứ. Ví dụ, các tập lệnh jQuery được sử dụng nhiều trong ASP.NET MVC nên được lưu trữ. Trên thực tế lý tưởng bạn nên sử dụng CDN cho những người đó, nhưng quan điểm của tôi là một số nội dung nên được lưu trữ.

Điều tôi thấy hoạt động tốt nhất ở đây thay vì rắc [OutputCache] ở mọi nơi là sử dụng một lớp:

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

Tất cả các bộ điều khiển của bạn mà bạn muốn tắt bộ đệm ẩn để kế thừa từ bộ điều khiển này.

Nếu bạn cần ghi đè mặc định trong lớp NoCacheControll, chỉ cần chỉ định cài đặt bộ đệm trên phương thức hành động của bạn và cài đặt trên phương thức Hành động của bạn sẽ được ưu tiên.

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

4
@Ozziepeeps, nhận xét của bạn không đúng. Các tài liệu msDN thảo luận về bộ nhớ đệm của trình duyệt cũng như một thử nghiệm đơn giản sẽ cho thấy thuộc tính này thay đổi tiêu đề phản hồi kiểm soát bộ đệm thành "Kiểm soát bộ đệm: công khai, không lưu trữ, max-age = 0" từ "Kiểm soát bộ đệm: riêng tư" mà không sử dụng thuộc tính.
Adam Tuliper - MSFT

2
cũng fyi - bạn có thể kiểm soát cả ba vị trí (máy chủ, proxy, máy khách) với thuộc tính này để hoàn toàn có thể kiểm soát ngoài bộ đệm của máy chủ. Xem asp.net/mvc/tutorials/ đá để biết thêm chi tiết.
Adam Tuliper - MSFT

1
+1 "Nếu bạn cần ghi đè mặc định trong lớp NoCacheControll chỉ cần chỉ định cài đặt bộ đệm trên phương thức hành động của bạn và cài đặt trên phương thức Hành động của bạn sẽ được ưu tiên."
Korayem

2
Xin lưu ý rằng nếu bạn sử dụng [System.Web.Mvc.OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]ở cấp độ lớp, bạn không thể có PartialViews trong lớp.
Sông Vivian

1
Phương thức OutputCache không ngăn bộ đệm IE khi có hai điều kiện: 1) hành động không có tham số và 2) hành động chỉ trả về văn bản qua Nội dung (someText). Khi tôi trả về JSON và lấy tham số, bộ nhớ đệm IE bị đánh bại đúng cách.
Kasey speakman

10

Bạn có thể muốn tắt bộ nhớ đệm trình duyệt cho tất cả các trang được hiển thị bởi bộ điều khiển (ví dụ: trang HTML), nhưng giữ bộ nhớ đệm tại chỗ cho các tài nguyên như tập lệnh, biểu định kiểu và hình ảnh . Nếu bạn đang sử dụng gói và thu nhỏ MVC4 +, bạn sẽ muốn giữ thời lượng bộ đệm mặc định cho tập lệnh và bảng định kiểu (thời lượng rất dài, do bộ đệm bị vô hiệu hóa dựa trên thay đổi thành một URL duy nhất, không dựa trên thời gian).

Trong MVC4 +, để tắt bộ nhớ đệm trình duyệt trên tất cả các bộ điều khiển, nhưng giữ lại nó cho bất kỳ thứ gì không được bộ điều khiển phục vụ, hãy thêm cái này vào FilterConfig.RegisterGlobalFilters:

filters.Add(new DisableCache());

Xác định DisableCachenhư sau:

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

Thật không may, điều này dường như không hoạt động, vì nhấn nút quay lại sau khi đăng xuất sẽ hiển thị trang.
ᴍᴀᴛᴛ

6

Tôi biết câu trả lời này không liên quan 100% đến câu hỏi, nhưng nó có thể giúp được ai đó.

Nếu bạn muốn vô hiệu hóa bộ đệm của trình duyệt cho toàn bộ Trang web ASP.NET MVC , nhưng bạn chỉ muốn thực hiện TẠM THỜI này, thì tốt hơn hết là tắt bộ đệm trong trình duyệt của bạn.

Đây là ảnh chụp màn hình trong Chrome


Đây chính xác là những gì tôi đang tìm kiếm ... trong quá trình phát triển, nếu tôi thay đổi tệp .js, sẽ rất khó khăn để vượt qua điều đó ngay lập tức khi tôi gặp khó khăn trong việc khắc phục sự cố / làm mới / kiểm tra chu kỳ. Điều này là hoàn hảo, cảm ơn bạn! Chỉ cần làm cho phía khách hàng của tôi gỡ lỗi cuộc sống dễ dàng hơn nhiều
jleach

2

Tôi đã thực hiện tất cả các câu trả lời trước đó và vẫn có một chế độ xem không hoạt động chính xác.

Hóa ra tên của quan điểm tôi gặp vấn đề được đặt tên là 'Gần đây'. Rõ ràng điều này làm bối rối trình duyệt Internet Explorer.

Sau khi tôi thay đổi tên xem (trong bộ điều khiển) thành một tên khác (tôi đã chọn thành 'Recent5'), các giải pháp ở trên bắt đầu hoạt động.


0

Bạn có thể thử mã dưới đây trong tệp Global.asax.

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

-1

Giao diện người dùng

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

Lý lịch

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

1
cần văn xuôi giải thích, ngay cả khi nó đúng về mặt kỹ thuật
rmalayter
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.