Asp.Net中MVC緩存詳解
本文通過介紹了Asp.Net中MVC緩存的種類,以及他們之間的區(qū)別等內容,讓學習者能夠深入的了解MVC緩存的原理機制,以下是具體內容:
緩存是一種保存資源副本并在下次請求時直接使用該副本的技術。當 web 緩存發(fā)現(xiàn)請求的資源已經被存儲,它會攔截請求,返回該資源的拷貝。
Web應用緩存技術大體上可以分為兩類:服務端緩存和客戶端緩存。兩種目標都是減少重復性內容的生成和網絡傳輸工作,因為緩存數(shù)據(jù)存儲的位置不同,而分為服務端緩存和客戶端緩存。
服務端緩存
服務端緩存技術關注于服務端數(shù)據(jù)查詢,生成或者操作技術。主要就是減少處理請求的工作量,減少數(shù)據(jù)庫查詢次數(shù)和生成HTML數(shù)據(jù)的CPU周期--減少每個bit的數(shù)據(jù)。
對于服務端緩存來說,不管是刷新頁面,重新輸入地址,還是Control+F5都不會規(guī)避緩存,如果緩存數(shù)據(jù)有效,一定是請求的緩存數(shù)據(jù)。
輸出緩存(Output Cache)
輸出緩存是Asp.Net下最常用的緩存機制。輸出緩存,緩存服務端生成的HTML數(shù)據(jù)--緩存Action下返回數(shù)據(jù)(Html/Json)。這樣,在每次調用相同的Action時,就不需要再次執(zhí)行Action方法。
緩存位置(Location)
OutputCache
使緩存的內容一般放在三個位置上:服務端,代理服務器,瀏覽器客戶端。通過Loaction
屬性可以設置緩存的位置。
Loaction
屬性有如下值:
Any Client Downstream Server None ServerAndClient
默認值為Any
,就是在三個位置都會緩存。但是應該根據(jù)不同的情況使用不同的緩存位置。比如:要緩存的內容是針對特定用戶的,每個用戶都會不同。這樣的話,該緩存就不能保存在服務器上。應該保存在瀏覽器客戶端上。
使用Output Cache
在Controller
或者Action
上添加[OutputCache]
特性,使得被添加的Controller
或Action
可以緩存返回的數(shù)據(jù)。(在Action
添加會緩存當前的Action
,在Controller
會緩存該Controller
下的所有Action
)
如下代碼:當?shù)谝淮畏椒ㄔ揂ction時,開始計時10秒,此10秒內所有訪問該Action的請求都會請求緩存數(shù)據(jù)。當10秒結束后,再重新開始等待新一次請求,開始新的10秒緩存。就是每隔10秒丟掉舊緩存,等待新的請求,更新緩存數(shù)據(jù)。
using System.Web.Mvc; using System.Web.UI; namespace MvcApplication1.Controllers { public class HomeController : Controller { //緩存時間10秒,緩存變量為無,緩存位置為服務端 [OutputCache(Duration=10, VaryByParam="none", Location = OutputCacheLocation.Server)] public ActionResult Index() { return View(); } } }
View:
@{ ViewBag.Title = "Index"; } <h2>Index</h2> <p>@DateTime.Now.ToString()</p>
點擊F12,查看請求
需要注意的是:
該緩存時間是絕對時間。此緩存是對所有訪問該頁面的用戶都有效。不能保證緩存一定有效。當內存資源不夠時,緩存就會自動地將沒用的或者優(yōu)先級低緩存清除。
客戶端緩存
除了服務端緩存外,客戶端也可以緩存數(shù)據(jù)。它避免了向服務器重復提交獲取重復數(shù)據(jù)的請求,把一些重復數(shù)據(jù)緩存到本地。服務端緩存是為了更快的處理客戶端請求,而客戶端緩存則是為了避免不必要的請求。
(瀏覽器會自動把靜態(tài)資源緩存到瀏覽器)
MVC中指定Location
值為OutputCacheLocation.Client
使緩存在瀏覽器客戶端上。
using System.Web.Mvc; using System.Web.UI; namespace MvcApplication1.Controllers { public class BadUserController : Controller { //緩存時間為10秒,緩存參數(shù)為無,緩存位置為客戶端 [OutputCache(Duration = 10, VaryByParam = "none",Location = OutputCacheLocation.Client)] public ActionResult ClientCache() { return View(); } } }
@{ ViewBag.Title = "ClientCache"; } <h2>ClientCache</h2> <p>@DateTime.Now.ToString()</p>
客戶端緩存和服務端緩存不一樣。
刷新,重新輸入地址,和Control+F5都有可能破壞客戶端緩存,從服務端重新獲取數(shù)據(jù)。
瀏覽器刷新,和重新輸入地址會避免請求該URL頁面的客戶端緩存,只避免請求該URL頁面的緩存。(如果該頁面有其他URL是被客戶端緩存的,這些資源或頁面的緩存不會被避免)。
那么什么情況下客戶端緩存才有效?
通過URL訪問,客戶端緩存才有效。
比如:
頁面A是客戶端緩存,同時頁面A有一個跳向頁面B的鏈接。通過A到達頁面B,同時頁面B也有一個鏈接,這個鏈接跳向A。通過B再次訪問A,此時頁面A獲取的數(shù)據(jù)就是客戶端的緩存數(shù)據(jù),并沒有請求服務端,是沒有請求服務端。不是304,status-code依然是200。 Status-Code:304/200(from cache)
304
只有當客戶端和服務端同時都緩存了數(shù)據(jù)。且緩存沒有更新的時候,才會有304。即這個緩存是要到服務端驗證(根據(jù)ETag和If-Modify-Since),該緩存是否最新。如果要更新緩存,從服務端獲取數(shù)據(jù),status code:200,否則status code:304.
304 和200(from cache)區(qū)別
304是會到服務端去校驗一次當前客戶端緩存是否有效(根據(jù)ETag和If-Modify-Since)。而200(from cache)則沒有向服務端校驗,也沒有向服務端請求,直接使用了客戶端緩存。
有時我們又需要避免這種沒有向服務端請求,直接使用緩存的情況。解決辦法就是更改這個緩存的url,添加一個版本號或唯一值。這樣因為url的更改使得在客戶端沒有對應的url緩存,就會從服務端重新獲取,再緩存該URL的數(shù)據(jù)。
不同內容的輸出緩存
之前的緩存都是Action返回相同的內容。如果Action每次返回的內容不同,那又該怎么緩存這些不同的內容呢?
使用OutputCache
特性的VaryByParam
屬性來解決這個問題。當表單參數(shù)或查詢字符串參數(shù)變化時,該屬性能夠創(chuàng)建同一個Action下不同的緩存。
如下代碼:Master 獲取列表。Details 獲取列表中選擇項的詳細內容。通過使用VaryByParam
來緩存不同的id
的列表項的詳細內容。
using System.Web.Mvc; namespace MvcApplication1.Controllers { public class MoviesController : Controller { public MoviesController() { } [OutputCache(Duration=int.MaxValue, VaryByParam="none")] public ActionResult Master() { //獲取列表 return View(); } [OutputCache(Duration = int.MaxValue, VaryByParam = "id")] public ActionResult Details(int id) { //根據(jù)參數(shù)id,從數(shù)據(jù)庫中獲取指定詳細內容,并緩存該內容。不同的id會得到不同的內容,自然也會有緩存。 //但是如果設置VaryByParam="none"那么不管id是多少,都直接從緩存中獲取數(shù)據(jù),不執(zhí)行該Action,這樣就會只返回第一次選擇項的數(shù)據(jù)。 return View(); } } }
Details()
操作包括一個帶有值“Id”的VaryByParam
屬性。當將Id參數(shù)的不同值傳遞給控制器操作時,將生成不同的緩存內容。
VaryByParam
可以根據(jù)參數(shù)緩存不同的內容
當VaryByParam="*"
: 每當表單或查詢字符串參數(shù)變化時,創(chuàng)建一個不同的緩存版本。當VaryByParam="none"
: 不創(chuàng)建不同的緩存內容,不根據(jù)參數(shù)緩存不同的內容,即只有一個內容的緩存。當VaryByParam="參數(shù)列表"
: 為不同的參數(shù)創(chuàng)建不同的緩存版本。
緩存配置
除了在OutputCache
特性上直接配置緩存策略,可以在web.config
文件中使用緩存配置文件,同一管理緩存的策略。使用配置文件相比直接使用屬性有如下幾點好處:
可以實現(xiàn)一次定義,多處使用。
可以修改web配置文件,而無需重新編譯應用程序。(如果想把已經部署到生產環(huán)境中的應用程序禁用緩存,可以修改web配置文件中定義的緩存配置。對web配置文件的任何更改都將被自動檢測并應用。)
例如,web.config部分定義了一個名為“cache1Hour”的緩存配置文件。使用該配置項時,只需指定CacheProfile=配置項名稱即可。
<caching> <outputCacheSettings> <outputCacheProfiles> <add name="Cache1Hour" duration="3600" varyByParam="none"/> </outputCacheProfiles> </outputCacheSettings> </caching>
using System; using System.Web.Mvc; namespace MvcApplication1.Controllers { public class ProfileController : Controller { //配置文件中的緩存策略名稱賦值給CacheProfile [OutputCache(CacheProfile="Cache1Hour")] public string Index() { return DateTime.Now.ToString(); } } }
簡單介紹下Http緩存的頭相關信息:
消息頭 | 值 | 類型 | 說明 |
---|---|---|---|
Expires | Thu, 30 Nov 2017 08:21:14 GMT | 響應 | 過期時間,為格林威治時間 (GMT) |
Pragma | no-cache | 響應 | 忽略瀏覽器緩存(Http1.1用Cache-Control代替) |
Cache-Control | no-cache | 請求/響應 | 客戶端緩存驗證 |
Cache-Control | no-store | 請求/響應 | 不在任何地方保存數(shù)據(jù),不允許被緩存 |
Cache-Control | max-age=[秒] | 請求/響應 | 設置瀏覽器緩存最長時間 |
Cache-Control | public | 響應 | 緩存在任何地方 |
Cache-Control | private | 響應 | 緩存該用戶的瀏覽器 |
Last-Modified | Thu, 30 Nov 2017 08:21:14 GMT | 響應 | 告訴瀏覽器服務端最后一次修改的時間 |
If-Modified-Since | Thu, 30 Nov 2017 08:21:14 GMT | 請求 | 如果瀏覽器中Last-Modofied有值,在請求中把值給If-Modified-Since,提交給服務端 |
ETag | 3df04c15b968d31:0 | 響應 | 該資源及其版本在服務端的唯一標識 |
If-None-Match | 3df04c15b968d31:0 | 請求 | 把上次請求中獲取到的ETag值,賦值給If-None-Match并提交給服務端 |
Vary | Accept-Encoding | 響應 | 從多個緩存副本中選擇匹配的版本 |
有幾個容易理解錯誤的點
no-cache: 使用no-cache 指令的目的是為了防止從緩存中使用過期的資源,所以每次使用緩存時都要到服務端去驗證。從字面意思上很容易把no-cache誤解成為不緩存,但事實上no-cache代表不緩存過期的資源,緩存會向源服務器進行有效期確認后處理資源。
no-store: 不存儲客戶端相關請求或服務器響應的任何內容,即真正的不緩存。
上一篇:C#實現(xiàn)將一個字符串進行翻轉顯示的6種方法
欄 目:C#教程
下一篇:C#利用Task實現(xiàn)任務超時多任務一起執(zhí)行的方法
本文標題:Asp.Net中MVC緩存詳解
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5342.html
您可能感興趣的文章
- 01-10C#通過反射獲取當前工程中所有窗體并打開的方法
- 01-10C#實現(xiàn)Winform中打開網頁頁面的方法
- 01-10C#實現(xiàn)由四周向中心縮小的窗體退出特效
- 01-10Extjs4如何處理后臺json數(shù)據(jù)中日期和時間
- 01-10C#中DataGridView常用操作實例小結
- 01-10C#編程獲取資源文件中圖片的方法
- 01-10asp.net中XML如何做增刪改查操作
- 01-10C#利用反射技術實現(xiàn)去掉按鈕選中時的邊框效果
- 01-10C#中查找Dictionary中的重復值的方法
- 01-10C#中TreeView實現(xiàn)適合兩級節(jié)點的選中節(jié)點方法


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10C#中split用法實例總結
- 04-02jquery與jsp,用jquery
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10delphi制作wav文件的方法
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改