[转载]MVC3缓存之二:页面缓存中的局部动态 – 好记性不如烂键盘 – 博客园.
在上一篇我们讨论了MVC中使用页面缓存的一些方法,而其中由于页面缓存的粒度太粗,不能对页面进行局部的缓存,或者说,如果我们想在页面缓存的同时对局部进行动态输出该怎么办?下面我们看下这类问题的处理。
MVC中有一个Post-cache substitution的东西,可以对缓存的内容进行替换。
使用Post-Cache Substitution
- 定义一个返回需要显示的动态内容string的方法。
- 调用HttpResponse.WriteSubstitution()方法即可。
示例,我们在Model层中定义一个随机返回新闻的方法。
using System; using System.Collections.Generic; using System.Web; namespace MvcApplication1.Models { public class News { public static string RenderNews(HttpContext context) { var news = new List { "Gas prices go up!", "Life discovered on Mars!", "Moon disappears!" }; var rnd = new Random(); return news[rnd.Next(news.Count)]; } } }
然后在页面中需要动态显示内容的地方调用。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %> <%@ Import Namespace="MvcApplication1.Models" %> Index <div><% Response.WriteSubstitution(News.RenderNews); %> <hr /> The content of this page is output cached. <%= DateTime.Now %></div>
如在上一篇文章中说明的那样,给Controller加上缓存属性。
using System.Web.Mvc; namespace MvcApplication1.Controllers { [HandleError] public class HomeController : Controller { [OutputCache(Duration=60, VaryByParam="none")] public ActionResult Index() { return View(); } } } [/chsarp] 可以发现,程序对整个页面进行了缓存60s的处理,但调用WriteSubstitution方法的地方还是进行了随机动态显示内容。 对Post-Cache Substitution的封装 将静态显示广告Banner的方法封装在AdHelper中。 using System; using System.Collections.Generic; using System.Web; using System.Web.Mvc; namespace MvcApplication1.Helpers { public static class AdHelper { public static void RenderBanner(this HtmlHelper helper) { var context = helper.ViewContext.HttpContext; context.Response.WriteSubstitution(RenderBannerInternal); } private static string RenderBannerInternal(HttpContext context) { var ads = new List { "/ads/banner1.gif", "/ads/banner2.gif", "/ads/banner3.gif" }; var rnd = new Random(); var ad = ads[rnd.Next(ads.Count)]; return String.Format("<img src="{0}" alt="" />", ad); } } }
这样在页面中只要进行这样的调用,记得需要在头部导入命名空间。
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Index.aspx.cs" Inherits="MvcApplication1.Views.Home.Index" %> <%@ Import Namespace="MvcApplication1.Models" %> <%@ Import Namespace="MvcApplication1.Helpers" %> Index <div><% Response.WriteSubstitution(News.RenderNews); %> <hr /> <% Html.RenderBanner(); %> <hr /> The content of this page is output cached. <%= DateTime.Now %></div>
使用这样的方法可以使得内部逻辑对外呈现出更好的封装。