在本章中,我们将重点介绍最常见的ASP.NET技术之一(如缓存),以提高应用程序的性能,缓存意味着将某些东西存储在内存中,这些东西经常被使用以提供更好的性能,我们将看到如何利用输出缓存来显着提高ASP.NET MVC应用程序的性能。
在ASP.NET MVC中,您可以应用一个OutputCache筛选器属性,这与Web表单中的输出缓存相同,通过输出缓存,您可以缓存控制器操作返回的内容。
输出缓存基本上使您可以将特定控制器的输出存储在内存中,因此,将来从该缓存输出中返回对该控制器中的相同Action的任何请求。这样,不必每次调用同一控制器Action时都生成相同的内容。
为什么要缓存?
我们需要在许多不同的场景中进行缓存,以提高应用程序的性能。如,您有一个ASP.NET MVC应用程序,该应用程序显示员工列表。现在,每当用户每次调用控制器操作时通过执行数据库查询从数据库中检索这些记录时,它将返回Index视图。
因此,您可以利用输出缓存来避免每次用户调用相同的控制器操作时都执行数据库查询,在这种情况下,将从缓存中检索视图,而不是从控制器操作中重新生成视图。
通过缓存,您可以避免在服务器上执行多余的工作。
让我们看一下我们项目中缓存的简单示例。
[OutputCache(Duration = 60)] public ActionResult Index(){ var employees = from e in db.Employees orderby e.ID select e; return View(employees); }
如您所见,我们在EmployeeController的index操作上添加了"OutputCache"属性,现在要了解这个概念,让我们在调试器模式下运行此应用程序,并在Index action方法中插入一个断点。

指定以下URL http://localhost:63004/employee ,然后按回车,您将看到在Index操作方法中命中了断点。

按" F5"按钮继续,您将在视图中看到从数据库中检索到的员工列表。

在60秒内再次刷新浏览器,您会发现这次没有找到断点,这是因为我们使用了持续时间为几秒的输出缓存,因此它将缓存此输出60秒钟,并且当您刷新浏览器时,它将从缓存中获取输出,并且不会从数据库服务器加载内容。
除了持续时间参数外,还有其他设置选项可与输出缓存一起使用,这些设置不仅适用于MVC框架,而且还继承自ASP.Net Caching。
改变输出缓存
在某些情况下,您可能需要不同的缓存版本,如,当创建详细信息页面时,然后单击详细的链接时,您将获得所选员工的详细信息。
但是首先我们需要创建细节视图。为此,在EmployeeController上的Details操作方法上单击鼠标右键,然后选择Add View…。

您将看到默认情况下选择了Details名称。现在,从"Template"下拉列表中选择"Details",从"Model"类下拉列表中选择"Employee"。

点击"Add"继续,您将看到Details.cshtml。
@model MVCSimpleApp.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>
</span><span class="str"><dd></span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">DisplayFor</span><span class="pun">(</span><span class="pln">model </span><span class="pun">=></span><span class="pln"> model</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">)</span><span class="pln">
</span><span class="pun"></</span><span class="pln">dd</span><span class="pun">></span><span class="pln">
</span><span class="str"><dt></span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">DisplayNameFor</span><span class="pun">(</span><span class="pln">model </span><span class="pun">=></span><span class="pln"> model</span><span class="pun">.</span><span class="typ">JoiningDate</span><span class="pun">)</span><span class="pln">
</span><span class="pun"></</span><span class="pln">dt</span><span class="pun">></span><span class="pln">
</span><span class="str"><dd></span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">DisplayFor</span><span class="pun">(</span><span class="pln">model </span><span class="pun">=></span><span class="pln"> model</span><span class="pun">.</span><span class="typ">JoiningDate</span><span class="pun">)</span><span class="pln">
</span><span class="pun"></</span><span class="pln">dd</span><span class="pun">></span><span class="pln">
</span><span class="str"><dt></span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">DisplayNameFor</span><span class="pun">(</span><span class="pln">model </span><span class="pun">=></span><span class="pln"> model</span><span class="pun">.</span><span class="typ">Age</span><span class="pun">)</span><span class="pln">
</span><span class="pun"></</span><span class="pln">dt</span><span class="pun">></span><span class="pln">
</span><span class="str"><dd></span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">DisplayFor</span><span class="pun">(</span><span class="pln">model </span><span class="pun">=></span><span class="pln"> model</span><span class="pun">.</span><span class="typ">Age</span><span class="pun">)</span><span class="pln">
</span><span class="pun"></</span><span class="pln">dd</span><span class="pun">></span><span class="pln">
</span><span class="pun"></</span><span class="pln">dl</span><span class="pun">></span><span class="pln">
</span><span class="pun"></</span><span class="pln">div</span><span class="pun">></span><span class="pln">
</span><span class="str"><p></span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">ActionLink</span><span class="pun">(</span><span class="str">"Edit"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Edit"</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> id </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Model</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">})</span><span class="pln"> </span><span class="pun">|</span><span class="pln">
</span><span class="lit">@Html</span><span class="pun">.</span><span class="typ">ActionLink</span><span class="pun">(</span><span class="str">"Back to List"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"Index"</span><span class="pun">)</span><span class="pln">
</span><span class="pun"></</span><span class="pln">p</span><span class="pun">></span><span class="pln">
</body>
</html>
您可以利用[OutputCache]属性的VaryByParam属性,此属性使您可以在表单参数或查询字符串参数变化时为同一内容创建不同的缓存版本,以下是"Details"操作的实现。
//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); }
编译并执行上述代码后,通过指定URL http://localhost:63004/employee 将收到以下输出。

单击任何链接的"Details"链接,您将看到该特定员工的详细信息视图。

Details()操作包含值为" Id"的VaryByParam属性,将Id参数的不同值传递到控制器操作时,将生成"Details"视图的不同缓存版本。
重要的是要了解使用VaryByParam属性会导致更多的缓存,将为Id参数的每个不同版本创建一个详细信息视图的不同缓存版本。
缓存配置文件
您可以在web.config文件中创建缓存配置文件,它是通过修改[OutputCache]属性来配置输出缓存属性的替代方法。
通过在web.config文件中创建缓存配置文件,让我们看一个简单的缓存配置文件示例。<caching>部分必须出现在<system.web>部分中。
<caching> <outputCacheSettings> <outputCacheProfiles> <add name = "Cache10Min" duration = "600" varyByParam = "none"/> </outputCacheProfiles> </outputCacheSettings> </caching>
您可以使用[OutputCache]属性将Cache10Min配置文件应用于控制器操作,如下所示。
[OutputCache(CacheProfile = "Cache10Min")]public ActionResult Index(){ var employees = from e in db.Employees orderby e.ID select e; return View(employees); }
运行此应用程序并指定以下URL http://localhost:63004/employee

如果您如上所示调用Index()操作,则将返回10分钟的相同时间。