本文总阅读量:  次 | 文章总字数: 2,643 字

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<string>   

                {   

                    "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 %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=”http://www.w3.org/1999/xhtml" >

<head runat=”server”>

<title>Index</title>

</head>

<body>

<div>

<% Response.WriteSubstitution(News.RenderNews); %>

<hr />

The content of this page is output cached.

<%= DateTime.Now %>

</div>

</body>

</html>

如在上一篇文章中说明的那样,给Controller加上缓存属性。

using System.Web.Mvc;

namespace MvcApplication1.Controllers

{

[HandleError]

public class HomeController : Controller

{

[OutputCache(Duration
=60, VaryByParam=none)]

public ActionResult Index()

{

return View();

}

}



}

可以发现,程序对整个页面进行了缓存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<string>

{

/ads/banner1.gif,

/ads/banner2.gif,

/ads/banner3.gif

};

var rnd
= new Random();

var ad
= ads[rnd.Next(ads.Count)];

return String.Format(, ad);

}

}


}

这样在页面中只要进行这样的调用,记得需要在头部导入命名空间。

<%@ Page Language=C# AutoEventWireup=true CodeBehind=Index.aspx.cs Inherits=MvcApplication1.Views.Home.Index %>

<%@ Import Namespace=MvcApplication1.Models %>

<%@ Import Namespace=MvcApplication1.Helpers %>

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=”http://www.w3.org/1999/xhtml" >

<head runat=”server”>

<title>Index</title>

</head>

<body>

<div>

<% Response.WriteSubstitution(News.RenderNews); %>

<hr />

<% Html.RenderBanner(); %>

<hr />

The content of this page is output cached.

<%= DateTime.Now %>

</div>

</body>

</html>

使用这样的方法可以使得内部逻辑对外呈现出更好的封装。

EOF

转载须以超链接形式标明文章原始出处和作者信息