在上一篇我们讨论了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)];
}
}
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 >
<% @ 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();
}
}
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( " <img src='{0}' /> " , ad);
}
}
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( " <img src='{0}' /> " , 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 >
<% @ 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>
使用这样的方法可以使得内部逻辑对外呈现出更好的封装。
作者:Parry
出处:http://www.cnblogs.com/parry/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。