Welcome 微信登录

首页 / 网页编程 / ASP.NET / 适合ASP.NET MVC的视图片断缓存方式(中):更实用的API

适合ASP.NET MVC的视图片断缓存方式(中):更实用的API2011-10-04 博客园 赵劼上一篇文章中我们提出了了片断缓存的基本方式,也就是构建HtmlHelper的扩展方法Cache,接受一个 用于生成字符串的委托对象。在缓存命中时,则直接返回缓存中的字符串片断,否则则使用委托生成的内 容。因此,缓存命中时委托的开销便节省了下来。不过这个方法并不实用,如果您要缓存大片的HTML,还 需要准备一个Partial View,再用它来生成网页片段:

<%= Html.Cache(..., () => Html.Partial("MyPartialViewToCache")) % >

但是在实际开发过程中,我们最乐于看到的使用方法,应该只是使用某个标记来“围绕”一段现有的 代码。也就是说,我们希望的API使用方式可能是这样的:

<% Html.Cache("cache_key", DateTime.Now.AddSeconds(10), () => { % >

<% foreach (var article in Model.Articles) { %>
<p><%= article.Body %></p>
<% } %>

<% }); % >

我们可以从这种“表现形式”上推断出这个Cache方法的签名:

public static void Cache(
this HtmlHelper htmlHelper,
string cacheKey,
CacheDependency cacheDependencies,
DateTime absoluteExpiration,
TimeSpan slidingExpiration,
Action action)
{
...
}

与前一个扩展相比,最后一个委托参数变成了Action,而不是Func<string>。这是因为ASP.NET 页面在编译时,会将页面Cache块中的代码,编译为内容的输出方式——这点在之前的文章中已经有过比 较详细的描述。不过有一点还是与之前相同的,我们要省下的是action委托的开销。也就是说,如果缓存 命中,则不执行action。缓存没有命中,则执行action,获得action生成的字符串,加入缓存并输出。

看似比较简单,但这里有个问题:如之前的Func<string>参数,我们执行后自然可以获得一个 字符串作为结果。但是现在是个action,执行后它又把内容输出到什么地方去,我们又该如何得到这里生 成的字符串呢?根据页面输出行为,我们可以推断出页面上的内容是被写入一个HtmlTextWriter中的。那 么,这个HtmlTextWriter又是如何生成的呢?

它是根据Page类型的CreateHtmlTextWriter方法生成的:

protected virtual HtmlTextWriter CreateHtmlTextWriter(System.IO.TextWriter tw) { ... }