代码改变世界

BlogEngine.Net架构与源代码分析系列part12:页面共同的基类——BlogBasePage

2008-11-13 12:05  GUO Xingwang  阅读(4226)  评论(7编辑  收藏  举报

     上一篇文章我向大家展示了BlogEngine.Net中Theme的原理和一些开发规范,里面有很多内容和这篇文章有着联系,建议大家这两篇文章结合在一起看,这样效果会更好。在这篇文章中我主要向大家说明BlogBasePage,PostViewBase,CommentViewBase这三个类的内部实现上的一些技巧以及它们与页面,文章和评论之间是如何组织在一起的,希望对大家阅读这部分代码有帮助。

     认识一下它们

     BlogBasePage,PostViewBase,CommentViewBase它们都是一些元素的基类,首先把这些元素定义成基类,然后使用继承的方式实现我认为主要有以下好处:

1.代码复用会得到提升,对于一些大量的同样操作都可以放在基类中,子类直接可以继承使用。

2.职责清晰,例如在Theme中的CommentView.ascx直接继承CommentViewBase就行了,CommentView.ascx只是来处理将Comment如何展现的问题。

3.规范化,这是继承带来的一个很重要的好处,因为子类就是一个父类,只要它是就可以使用

BlogBasePage:Web站点的根目录下的每一个页面都是从它继承而来,BlogBasePage继承自Page。而页面不是直接从Page继承而来。
PostViewBase:是一个Post显示功能部分的基类,themes中每个主题的PostView.ascx都是直接从它继承而来,PostViewBase继承自UserControl。
CommentViewBase:是一个Comment显示功能部分的基类,themes中每个主题的CommentView.ascx都是直接从它继承而来,CommentViewBase继承自UserControl。

     实现分析

     BlogBasePage到底都做了些什么?

OnPreInit中主要完成根据BlogSetting中的Theme找到相应的页面的Master文件(包括主题选择时的预览判断),此外还处理了Post的删除。
OnLoad中做得事情很多,主要是在head中加入一些资源引用(包括SIOC,APML,FOAF等),实际上就是当我们打开页面查看源代码看到head中多如牛毛的link。还有增加一些脚本的全局变量,增加BlogSetting中的自定义Head的html,增加track脚本,增加脚本引用(通过JavaScriptHandler来实现),增加样式(注意css的压缩是通过CssHandler实现的)。
OnPreRenderComplete中完成了标题的设置。
OnError中还对使用Comment的恶意攻击做了处理。

protected override void OnError(EventArgs e)
{
    HttpContext ctx 
= HttpContext.Current;
    Exception exception 
= ctx.Server.GetLastError();

    
if (exception != null && exception.Message.Contains("callback"))
    {
        
// This is a robot spam attack so we send it a 404 status to make it go away.
        ctx.Response.StatusCode = 404;
        ctx.Server.ClearError();
        Comment.OnSpamAttack();
    }

    
base.OnError(e);
}

 

     PostViewBase到底都做了些什么?

PostViewBase是一个用户控件,主要是显示一个Post,内部除了一些Post属性外,还有CommentFeed(通过SyndicationHandler处理),增加分类链接,增加Tag链接,增加管理链接,增加评分的脚本来给文章评分等。此外在Page_Load还对加入内容中的一个自定义的控件标签进行了特殊的处理,这种格式如:[UserControl:~/path/usercontrol.ascx],使用一个正则来判断,如果内容中有这种标签,那么内容显示时使用加载的控件来代替。

     CommentViewBase到底都做了些什么?

CommentViewBase是一个用户控件,主要是显示一个Comment,内部除了Comment和Post属性外,还有内容,管理链接,国旗显示,Gravatar显示等。请大家留意一下后面的两个图片的显示处理。

     了解了这些,上一篇文章中讲述的Theme中的几个必要文件的数据显示问题就清晰多了吧。

     页面的继承与组织关系

     这部分没有什么原理性的东西,只是帮助大家快速阅读代码而做的一个文件的介绍。

login.aspx:继承BlogBasePage,完成登录,注销,修改密码等与登录有关的用户接口。
default.aspx:继承BlogBasePage,内部使用PostList.ascx用户控件完成文章的列表显示接口。
search.aspx:继承BlogBasePage,用一个repeater显示搜索结果,这个以前提及过。
archive.aspx:继承BlogBasePage,对文章的归档显示,注意它的归档的处理过程。
contact.aspx:继承BlogBasePage,主要是完成阅读者给文章的发布者发送邮件。注意它还实现了ICallbackEventHandler,来完成ajax回调提交。
error404.aspx:继承BlogBasePage,404错误转向。
page.aspx:继承BlogBasePage,完成删除Page,显示Page(注意对注入控件显示的处理和与Post区别)。
post.aspx:继承BlogBasePage,完成文章的显示,使用User controls/CommentView.ascx来完成评论列表的显示和评论的提交。Page_Init中动态加载PostViewBase,处理了“上一篇”和“下一篇”等导航链接(需要Post类本身的支持),phRDF完成了Trackback的接收(以前文章提及过)。
对于Theme中的文件上文已经讲过,这里就不再多说。
对于admin/Pages中的这些管理页面都是直接继承自Page,Master为admin1.master,在Web.config中定义了访问权限等,这主要是实现了前端页面和后台管理的分开处理。
blog.js是BlogEngine.Net的所有脚本文件,里面封装Ajax处理(例如回调,评论的在线浏览等)。

     总结

     像BlogEngine.Net这种将几乎所有页面的Page再进行一下自定义的封装的处理方式在很多项目中都会得到应用,这一点我觉得很好。对于注入控件的处理方式也值得我们去学习。这种注入控件我想主要是完成一些外部资源的引入问题的,把文章或Page的显示交给这个用户控件来处理会很灵活。

     麻雀虽小,五脏俱全

     上一篇:BlogEngine.Net架构与源代码分析系列part11:开发扩展(下)——自定义Theme

     下一篇:BlogEngine.Net架构与源代码分析系列part13:实现分析(上)——HttpHandlers与HttpModules

 

     返回到目录