在本章中,我們將重點(diǎn)介紹最常用的ASP.NET技術(shù)之一:緩存,以提高應(yīng)用程序的性能。 在內(nèi)存中存儲(chǔ)經(jīng)常使用的內(nèi)容以提供更好的性能。我們將看到如何通過利用輸出緩存來顯著提高ASP.NET MVC應(yīng)用程序的性能。
在ASP.NET MVC中,可以應(yīng)用OutputCache篩選器屬性,這與Web表單中輸出緩存的概念相同。 輸出緩存使您能夠緩存控制器操作返回的內(nèi)容。
輸出緩存基本上允許您將特定控制器的輸出存儲(chǔ)在內(nèi)存中。 因此,來自該控制器中的相同動(dòng)作的未來請(qǐng)求將從緩存結(jié)果中返回。 這樣,每次調(diào)用相同的控制器操作時(shí),都不需要生成相同的內(nèi)容。
我們需要緩存在許多不同的場景來提高應(yīng)用程序的性能。 例如,一個(gè)ASP.NET MVC應(yīng)用程序,它顯示一個(gè)雇員名單。 現(xiàn)在,當(dāng)每次用戶調(diào)用控制器動(dòng)作時(shí),通過執(zhí)行數(shù)據(jù)庫查詢從數(shù)據(jù)庫中檢索這些記錄時(shí),它將返回顯示到Index視圖中。
因此,可以利用輸出緩存來避免每次調(diào)用相同的控制器操作時(shí)執(zhí)行數(shù)據(jù)庫查詢。 在這種情況下,將從緩存中檢索視圖,而不是從控制器操作重新生成。
緩存使您可以避免在服務(wù)器上執(zhí)行冗余工作。
下面來看看如何在項(xiàng)目中使用緩存的一個(gè)簡單示例,為了方便演示,這里創(chuàng)建一個(gè)MVC Web項(xiàng)目:MVCCaching 。
注意:創(chuàng)建讀取數(shù)據(jù)庫表記錄請(qǐng)參考:http://www.yiibai.com/asp.net_mvc/asp.net_mvc_databases.html
參考以下代碼 -
using MVCCaching.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MVCCaching.Controllers
{
public class EmployeeController : Controller
{
private EmpDBContext db = new EmpDBContext();
// GET: Employee 使用緩存
[OutputCache(Duration = 60)]
public ActionResult Index()
{
var employees = from e in db.Employees
orderby e.ID
select e;
return View(employees);
}
... ...
}
}
如您所見,在EmployeeController的Index動(dòng)作上添加了“OutputCache”屬性。 現(xiàn)在理解這個(gè)概念,在調(diào)試器模式下運(yùn)行這個(gè)應(yīng)用程序,并在Index操作方法中插入一個(gè)斷點(diǎn)。
按‘F5’按鈕繼續(xù),將看到視圖中有從數(shù)據(jù)庫中檢索到的員工列表。
在60秒內(nèi)再次刷新瀏覽器,會(huì)看到這個(gè)斷點(diǎn)沒有經(jīng)過。 這是因?yàn)槭褂昧溯敵鼍彺?,持續(xù)時(shí)間為幾秒。 所以它會(huì)把這個(gè)結(jié)果緩存60秒,當(dāng)刷新瀏覽器時(shí),它會(huì)從緩存中讀取得到結(jié)果,而不會(huì)從數(shù)據(jù)庫服務(wù)器加載內(nèi)容。
除了持續(xù)時(shí)間參數(shù)之外,還有其他一些設(shè)置選項(xiàng),可以使用輸出緩存。 這些設(shè)置不僅適用于MVC框架,而且是從ASP.Net緩存繼承的。
在某些情況下,可能需要不同的緩存版本,例如,當(dāng)創(chuàng)建詳細(xì)信息頁面時(shí),當(dāng)單擊詳細(xì)鏈接時(shí),將獲得所選員工的詳細(xì)信息。
但首先需要?jiǎng)?chuàng)建詳細(xì)視圖。 為此,請(qǐng)右鍵單擊EmployeeController中的Details操作方法,然后選擇添加視圖…
在默認(rèn)情況下選擇了詳細(xì)信息名稱?,F(xiàn)在從“模板”下拉列表中選擇Details,從“模型”下拉列表中選擇Employee -
點(diǎn)擊“添加”繼續(xù),會(huì)看到生成了文件:Details.cshtml。參考以下代碼 -
@model MVCCaching.Models.Employee
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Details</title>
</head>
<body>
<div>
<h4>Employee</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
@Html.DisplayFor(model => model.Name)
</dd>
<dt>
@Html.DisplayNameFor(model => model.JoiningDate)
</dt>
<dd>
@Html.DisplayFor(model => model.JoiningDate)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Age)
</dt>
<dd>
@Html.DisplayFor(model => model.Age)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.ID }) |
@Html.ActionLink("Back to List", "Index")
</p>
</body>
</html>
可以利用[OutputCache]屬性中的VaryByParam屬性。這個(gè)屬性使您能夠在表單參數(shù)或查詢字符串參數(shù)發(fā)生變化時(shí)創(chuàng)建不同的緩存版本。 以下是Details操作的實(shí)現(xiàn)。參考以下代碼 -
// GET: Employee/Details/5
[OutputCache(Duration = int.MaxValue, VaryByParam = "id")]
public ActionResult Details(int id){
var employee = db.Employees.SingleOrDefault(e => e.ID == id);
return View(employee);
}
當(dāng)編譯并執(zhí)行上述代碼時(shí),訪問指定URL:http://localhost:59893/employee 應(yīng)該會(huì)得到以下輸出。
點(diǎn)擊任何一個(gè)詳細(xì)信息鏈接,將看到該特定員工的詳細(xì)信息視圖。

Details()操作包含值為“Id”的VaryByParam屬性。 當(dāng)Id參數(shù)的不同值傳遞給控制器操作時(shí),會(huì)生成不同的緩存版本的Details視圖。
理解使用VaryByParam屬性導(dǎo)致更多緩存是非常重要的。 為每個(gè)不同版本的Id參數(shù)創(chuàng)建不同的緩存版本的Details視圖。
可以在web.config文件中創(chuàng)建緩存配置文件。 可以通過修改[OutputCache]屬性來配置輸出緩存屬性。 它提供了幾個(gè)重要的優(yōu)點(diǎn),如下所示。
我們來看一個(gè)簡單的緩存配置文件示例,在web.config文件中創(chuàng)建緩存配置文件。 <caching>部分必須出現(xiàn)在<system.web>部分中。如下 -
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name = "Cache10Min" duration = "600" varyByParam = "none"/>
</outputCacheProfiles>
</outputCacheSettings>
</caching>
可以使用[OutputCache]屬性將Cache10Min配置文件應(yīng)用于控制器操作,如下所示。
[OutputCache(CacheProfile = "Cache10Min")]
public ActionResult Index(){
var employees = from e in db.Employees
orderby e.ID
select e;
return View(employees);
}
當(dāng)編譯并執(zhí)行上述代碼時(shí),訪問指定URL:http://localhost:63004/employee 應(yīng)該會(huì)得到以下輸出。
如果調(diào)用Index()動(dòng)作如上所示,那么同樣也將是緩存10分鐘。