快速业务通道

适合ASP.NET MVC的视图片断缓存方式(下):页面输出原则

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

上一篇文章里已经把Html.Cache打造成了非常具有可用性的API,需要缓存时我们只需在页面上做一个 标记即可:

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

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

<% }); % >

标记内部的写法和普通视图的写法相同,您可以for/foreach/if,也可以<%= %>,或者使用 RenderPartial等其他辅助方法输出内容,都会被一并缓存下来。只可惜,上次文章末尾我提到有些效果 是有前提的。

这个前提就是:某些RenderPartial和其他一些辅助方法的实现需要进行修改。好吧,再说的直接一些 :如果您使用标准的ASP.NET MVC,就无法使用RenderPartial的功能。我认为造成这种问题的原因是 ASP.NET MVC框架在实现时没有遵守页面内容输出的准则。所以我建议您使用MvcPatch项目进行ASP.NET MVC开发。

不过现在,我们还是来讨论一下准则吧。下面有些内容涉及到ASP.NET WebForm页面的输出方式,如果 您遇到了不理解的地方,可以去看一下这篇文章,它是我为“页面片段缓存”原理介绍而写的“铺垫”。

在普通情况下,一个ASP.NET页面输出时是向一个封装了Response.Output的HtmlTextWriter中写入内 容的:

而我们的片段缓存实现为了“捕获”某个缓存块输出的内容,则在HtmlTextWriter与Response.Output 之间又插入了一个RecordWriter:

那么,在缓存命中的时候,我们的Cache方法把缓存中的内容写到什么地方去了呢?

public static void Cache(
  this HtmlHelper htmlHelper, 
  ...)
{
  var content = ...

  if (content == null)
  {
     ...
  }
  else 
  {
    htmlHelper.Output.Write(content);
  }
} 

Output是什么?如果您观察ASP.NET MVC的源代码,您会发现HtmlHelper并没有这个属性。这是我在 MvcPatch中暴露出来的一个TextWriter,它便是当前正用于页面输出的HtmlTextWriter对象。因此,我这 里提出一个原则:如果您是在向页面输出内容,请务必将所有内容通过页面的Writer输出。

在原来的ASP.NET MVC实现中,由于无法从HtmlHelper中获得页面的Writer,因此如果需要输出内容, 则只能通过Response.Write方法,或由 Response.Output输出内容了。根据上图可知,如果我们直接从 Response.Output输出,那么这部分内容是无法被 RecordWriter捕获的。这意味着什么呢?这意味着,如 果我们上面不是通过HtmlHelper.Output,而是直接向 Response.Output输出,在Html.Cache嵌套的情况 下,内层缓存块的输出无法被外层缓存块捕获到。因此,如果内层缓存命中,而外层重新生成内容,则会 发现内层缓存块的内容被没有被外层记录下来。

我们可以想的再远一些。我们这种TextWriter的嵌套其实是一种什么模式呢?应该算是装饰器模式吧 。装饰器模式要求我们所有的输出都从链条的顶部输入,这样所有的“装饰”作用才会生效。如果我们获 取了其中的某一个环节,直接从这个环节输入参数,那么自然是失败的。这意味着……假如又有另外一个 组件在“行使”它的扩展权力呢?如果又有另一个组件,它在我们的RecordWriter外层又进行了包装呢? 我们的片断缓存解决方案是一种扩展,作为扩展方案,不应该破坏其他组件正常扩展的能力。因此,我们 需要从页面的Writer中输出内容。

一个很好的反例就是ASP.NET MVC框架,您看RenderPartial方法的输出目标是什么:Response.Output 。还有FormExtensions及MvcForm 对象的输出目标是什么:还是Respo

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号