MVC3缓存之一:使用页面缓存 在MVC3中要如果要启用页面缓存,在页面对应的Action前面加上一个OutputCache属性即可。 我们建一个Demo来测试一下,在此Demo中,在View的Home目录下的Index.cshtml中让页面输入当前的时间。 [csharp] view plaincopy 01.@{ 02. Layout = null; 03.} 04.<!DOCTYPE html> 05.<html> 06.<head> 07. <title>Index</title> 08.</head> 09.<body> 10. <div> 11. <h2> 12. 现在时间:@DateTime.Now.ToString("T")</h2> 13. </div> 14.</body> 15.</html> 在Controllers中添加对应的Action,并加上OutputCache属性。 [csharp] view plaincopy 01.[HandleError] 02.public class HomeController : Controller 03.{ 04. [OutputCache(Duration = 5, VaryByParam = "none")] 05. public ActionResult Index() 06. { 07. return View(); 08. } 09.} 刷新页面即可看到页面做了一个5秒的缓存。当页面中数据不是需要实时的呈现给用户时,这样的页面缓存可以减小实时地对数据处理和请求,当然这是针对整个页面做的缓存,缓存的粒度还是比较粗的。 缓存的位置 可以通过设置缓存的Location属性,决定将缓存放置在何处。 Location可以设置的属性如下: · Any · Client · Downstream · Server · None · ServerAndClient Location的默认值为Any。一般推荐将用户侧的信息存储在Client端,一些公用的信息存储在Server端。 加上Location应该像这样。 [csharp] view plaincopy 01.[HandleError] 02.public class HomeController : Controller 03.{ 04. [OutputCache(Duration = 5, VaryByParam = "none", Location = OutputCacheLocation.Client, NoStore = true)] 05. public ActionResult Index() 06. { 07. return View(); 08. } 09.} 缓存依赖 VaryByParam可以对缓存设置缓存依赖条件,如一个产品详细页面,可能就是根据产品ID进行缓存页面。 缓存依赖应该设置成下面这样。 在MVC3中对输出缓存进行了改进,OutputCache不需要手动指定VaryByParam,会自动使用Action的参数作为缓存过期条件。 [csharp] view plaincopy 01.[HandleError] 02.public class HomeController : Controller 03.{ 04. [OutputCache(Duration = int.MaxValue, VaryByParam = "id")] 05. public ActionResult Index() 06. { 07. return View(); 08. } 09.} 另一种通用的设置方法 当我们需要对多个Action进行统一的设置时,可以在web.config文件中统一配置后进行应用即可。 在web.config中配置下Caching节点 [csharp] view plaincopy 01.<caching> 02.<outputCacheSettings> 03. <outputCacheProfiles> 04. <add name="Cache1Hour" duration="3600" varyByParam="none"/> 05. </outputCacheProfiles> 06.</outputCacheSettings> 07.</caching> 那么在Action上使用该配置节点即可,这样的方法对于统一管理配置信息比较方便。 [csharp] view plaincopy 01.[HandleError] 02.public class HomeController : Controller 03.{ 04. [OutputCache(CacheProfile = "Cache1Hour")] 05. public ActionResult Index() 06. { 07. return View(); 08. } 09.} MVC3缓存之二:页面缓存中的局部动态 MVC中有一个Post-cache substitution的东西,可以对缓存的内容进行替换。 使用Post-Cache Substitution ?定义一个返回需要显示的动态内容string的方法。 ?调用HttpResponse.WriteSubstitution()方法即可。 示例,我们在Model层中定义一个随机返回新闻的方法。 [csharp] view plaincopy 01.using System; 02.using System.Collections.Generic; 03.using System.Web; 04. 05.namespace MvcApplication1.Models 06.{ 07. public class News 08. { 09. public static string RenderNews(HttpContext context) 10. { 11. var news = new List<string> 12. { 13. "Gas prices go up!", 14. "Life discovered on Mars!", 15. "Moon disappears!" 16. }; 17. 18. var rnd = new Random(); 19. return news[rnd.Next(news.Count)]; 20. } 21. } 22.} 然后在页面中需要动态显示内容的地方调用。 [csharp] view plaincopy 01.<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %> 02.<%@ Import Namespace="MvcApplication1.Models" %> 03.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 04.<html xmlns="http://www.w3.org/1999/xhtml" > 05.<head runat="server"> 06. <title>Index</title> 07.</head> 08.<body> 09. <div> 10. <% Response.WriteSubstitution(News.RenderNews); %> 11. <hr /> 12. The content of this page is output cached. 13. <%= DateTime.Now %> 14. </div> 15.</body> 16.</html> 如在上面文章中说明的那样,给Controller加上缓存属性。 [csharp] view plaincopy 01.using System.Web.Mvc; 02. 03.namespace MvcApplication1.Controllers 04.{ 05. [HandleError] 06. public class HomeController : Controller 07. { 08. [OutputCache(Duration=60, VaryByParam="none")] 09. public ActionResult Index() 10. { 11. return View(); 12. } 13. } 14.} 可以发现,程序对整个页面进行了缓存60s的处理,但调用WriteSubstitution方法的地方还是进行了随机动态显示内容。 对Post-Cache Substitution的封装 将静态显示广告Banner的方法封装在AdHelper中。 [csharp] view plaincopy 01.using System; 02.using System.Collections.Generic; 03.using System.Web; 04.using System.Web.Mvc; 05. 06.namespace MvcApplication1.Helpers 07.{ 08. public static class AdHelper 09. { 10. public static void RenderBanner(this HtmlHelper helper) 11. { 12. var context = helper.ViewContext.HttpContext; 13. context.Response.WriteSubstitution(RenderBannerInternal); 14. } 15. 16. private static string RenderBannerInternal(HttpContext context) 17. { 18. var ads = new List<string> 19. { 20. "/ads/banner1.gif", 21. "/ads/banner2.gif", 22. "/ads/banner3.gif" 23. }; 24. 25. var rnd = new Random(); 26. var ad = ads[rnd.Next(ads.Count)]; 27. return String.Format("<img src=‘{0}‘ />", ad); 28. } 29. } 30.} 这样在页面中只要进行这样的调用,记得需要在头部导入命名空间。 [csharp] view plaincopy 01.<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %> 02.<%@ Import Namespace="MvcApplication1.Models" %> 03.<%@ Import Namespace="MvcApplication1.Helpers" %> 04.<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 05.<html xmlns="http://www.w3.org/1999/xhtml" > 06.<head runat="server"> 07. <title>Index</title> 08.</head> 09.<body> 10. <div> 11. <% Response.WriteSubstitution(News.RenderNews); %> 12. <hr /> 13. <% Html.RenderBanner(); %> 14. <hr /> 15. The content of this page is output cached. 16. <%= DateTime.Now %> 17. </div> 18.</body> 19.</html> 使用这样的方法可以使得内部逻辑对外呈现出更好的封装。 MVC3缓存之三:MVC3中的局部缓存(Partial Page) MVC3版本中,新增了一个叫做Partial Page的东西,即可以对载入到当前页面的另外的一个View进行缓存后输出,这与我们之前讨论的局部动态刚好相反了,即之前我们进行这个页面的缓存,然后对局部进行动态输出,现在的解决方案是:页面时动态输出的,而对需要缓存的局部进行缓存处理。查来查去还没有看到局部动态的解决方案,所以我们先看看局部缓存的处理方法。 局部缓存(Partial Page) 我们先建立一个需要局部缓存的页面View,叫做PartialCache.cshtml,页面内容如下: [csharp] view plaincopy 01.<p>@ViewBag.Time2</p> 在其对应的Controller中添加对应的Action [csharp] view plaincopy 01.[OutputCache(Duration = 10)] 02.public ActionResult PartialCache() 03.{ 04. ViewBag.Time2 = DateTime.Now.ToLongTimeString(); 05. return PartialView(); 06.} 我们可以看到对其Action做了缓存处理,对页面进行缓存10秒钟。 而在Index的View中调用此缓存了的页面则需要这样: [csharp] view plaincopy 01.@{ 02. ViewBag.Title = "Index"; 03.} 04.<h2> 05. OutputCache Demo</h2> 06.<p> 07. No Cache</p> 08.<div>@DateTime.Now.ToLongTimeString() 09.</div> 10.<br /> 11.<p> 12. Partial Cache 10 mins 13.</p> 14.<div class="bar2">@Html.Action("PartialCache", "Index", null)</div> 运行后,我们刷新页面可以发现Index的主体没有缓存,而引用到的PartialCache进行了10秒缓存的处理。