Zendy

---勿在浮沙筑高台---

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
如何在Asp.Net1.1中实现页面模板(所谓的MasterPage技术)

----提供一种简单、直观、可扩展的MasterPage方案 

前言:

    我曾经对Asp.Net FrameWork Asp.net Page的对象模型有过一些研究,在平时对Asp.net中一些有趣的技术有过一些研究,比如MasterPage技术。在讨论WebForm的统一页面如何架构的技术方案时,当时有两种可选的方案:

1.       第一种方案是最原始的方案,在每个业务表单(aspx),除了包含自己关心的MasterPage 之外,都会包含TopBannerLeftBanner ,BottomBanner这些无关的部分。这种方案的缺点我这里不提了。

2.       第二种方案是提供一个统一页面模板:Default.aspx,该模板包含TopBannerLeftBanner , MasterPage BottomBanner共四部分,其中MasterPage是动态可变的。用户的所有页面请求都转向该Default.aspx页面,在URLQueryString中都会加上PageID。在响应客户的每次请求时,在每次加载时,Default.aspx会读取PageID的值,根据已经配置的关系,根据不同的PageID来动态加载不同的MasterPage。这种做法虽然解决了方案一中存在的问题,但是对于客户或者开发者来说都是很别扭的处理手法:需要PageID对应MasterPage这么一个弯需要拐。它的好处和缺点都显而易见。

 

???:

    能不能有一种方法,可以定义一个统一风格的页面模板,并且单独实现每一个只与业务有关表单页面(不包含公用的HTML模块);并且在浏览器请求每个业务表单时,呈现的又是那个统一风格页面模板,并在这个模板的Master区域嵌入自身的业务表单?在Asp.net1.1中解决这个问题的方法有很多,其中比较流行、成熟的方案是MasterPage技术!并且在Aspt.Net2.0中也已经提供了该技术(Aspt.Net2.0中如何实现的,我没有研究过。以下的研究都是Asp.net1.1下的技术)

 

MasterPage技术思路:

    所谓MasterPage技术,就是专门提供一个页面模板,该模板可以根据具体需求设计一个统一模板,比如有TopBannerLeftBannerMasterPageBottomBanner部分组成,如下图所示:

 

,开发人员所关心的各个业务表单页面不包含任何的TopBannerLeftBannerBottomBanne部分,只包含与业务有关的UI内容。如下图所示:

当在浏览器请求每个单独业务表单时,每个表单不是仅仅只呈现自己的内容,它会首先呈现加载页面模板,让后把与业务有关的UI内容嵌入到页面模板MasterPage区域(黄色区域)

 

MasterPage具体实现技术:

    关于如何实现MasterPage技术在互联网上由很多实现方案。比较有名的几个实例有:www.codeproject.com上的http://www.codeproject.com/aspnet/Frame_Work_Design.asp

www.cnblogs.cn上的http://mack.cnblogs.com/archive/2005/06/18/176869.html

其中,www.cnblogs.cn的设计方案是对www.codeproject.com的一种改进方案。这里我大概介绍一下他们的实现技术要点:

1.       首先他们开发了一个继承了HtmlFormWebControl,我这里暂且称之为 MasterPageForm

2.       在每个业务表单页面中,用这个MasterPageForm来代替HtmlForm,也就说,原始的aspx页面时这样的:
<
form id="Form1" method="post" runat="server">

    具体内容
    </form>

    改变之后便成了这样的形势:

    <MasterPageForm id="Form1" method="post" runat="server">

    具体内容
    </MasterPageForm>

3.       在加载每一个业务表单页面时, 当MasterPageForm被实例化时,MasterPageForm除了会执行HtmlForm的功能,也会把页面模板(其实是一个ascx),并把该页面模板ascx作为HtmlForm的第一个子控件,同时把业务表单页面中所有设计期的控件都移动到页面模板ascx中那个MasterPage(黄色)位置(具体可以通过PlaceHolder控件实现:在页面模板ascx中,添加一个PlaceHolder控件,作为MasterPage的抛锚位置,MasterPageForm在加载页面模板ascx后,会找到抛锚点PlaceHolder控件,把业务表单页面中所有设计期的控件都移动到这个PlaceHolder

4.       通过第三步,实际业务表单相当于拥有了一个页面模板,并且已经把原来的本身拥有的控件移动到了希望的位置。

5.       这样最后实际呈现给浏览器的结果也就是想要的结果了。

 

评价MasterPage实现技术

    MasterPage实现比较复杂,实现了多个WebControl,对使用者来说这个是不大不小的障碍,并且在每个具体的业务表单页面中,都要用那个自定义的MasterPageForm来包括内容,实在不是很清洁的做法。也就是说对WebControl的依赖性太高,而直观性、可控性、自扩展性不高!

    比如本来的业务面表单是这样的:

<asp:Panel id="Panel1" LEFT: 80px; TOP: 172px" runat="server">

    <asp:TextBox id="TextBox1" runat="server"></asp:TextBox>

    <asp:Button id="Button1" runat="server" Text="Button"></asp:Button>

    <asp:Label id="Label1" runat="server">Label</asp:Label>

</asp:Panel>

    应用MasterPage技术之后,变成如下所示:

<MasterPageForm id="Form1" method="post" runat="server">

    <asp:Panel id="Panel1" LEFT: 80px; TOP: 172px" runat="server">

        <asp:TextBox id="TextBox1" runat="server"></asp:TextBox>

        <asp:Button id="Button1" runat="server" Text="Button"></asp:Button>

        <asp:Label id="Label1" runat="server">Label</asp:Label>

    </asp:Panel>

<MasterPageForm>

 

实现一种直观、简单、易扩展、易可控的实现方案

    到底有没有一种方法,即可以使用前面所述的MasterPage技术带来的好处,又不想受他们的束缚?答案是有的,下面我将简易介绍一下这种直观的简单的实现方案!

   

    我这个方案是站在现有MasterPage的基础之上,取其精华,去其糟粕之后的产物!其实上面的MasterPage的实现方法的累赘就是:MasterPageForm。既然他是累赘,那我就干脆把他去掉!

    那去掉之后,那个页面模板ascx该如何载入呢?很简单,我让每个业务表单页面都从一个PageBase集成,由这个PageBase来负责页面模板ascx的载入。PageBase在载入页面模板ascx之后,还负责把业务表单页面的移动到页面模板ascxPlaceHolder抛锚处。如下图来表述这个过程更来得清楚:

 

设计期的结构图

 

 

 

 

 运行时结构图

   

    我这里提供了一个Demo(见附件,解压后,把AspNetTry目录作为Web共享),大家可以解压到本地,从中研究一下MasterPage技术。压缩包的内容我主要介绍一下,

    PageBase.cs 是指 所有业务表单页面的公共基类

    PageTemplate.ascx 是指 具体的页面模板ascx(有两个PlaceHolderMasterPlaceHolderTopRightPlaceHolder)

    PageTempleteInterface.cs 是提供给PageBase调用的借口类,里面定义了许多把控件插入到PlaceHolder抛锚处的接口函数。每个PageTemplate.ascx都要实现这个接口

    WebForm1.aspx 第一个页面类,会把它自己的有很多业务相关的设计期控件移动到PageTemplate.ascxMasterPlaceHolder处。

 

       WebForm2.aspx 第二个页面类,除了会把自己的PanelTopRight移动到PageTemplate.ascxTopRightPlaceHolder处之外,剩余的很多业务相关的设计期控件移动到PageTemplate.ascxMasterPlaceHolder处。

   

    另外WebForm1.aspxWebForm2.aspx 还支持ButtomSubmit提交,JavaScript脚本,Viewstate处理。详见代码。

   

    根据Demo/Files/caomao/AspNetTry.rar中的一些JaveScriptViewStateButton事件处理,暂时没有碰到什么问题,相信期间还会碰到其他问题,关于进一步的技术心得我会及时和大家分享!欢迎大家提出改进意见,让这个MasterPage更好用,我认为这个MasterPage在开发Asp.net 1.1的Web项目时能带来很大的便利

 

    Thanks! 

 

 
 
posted on 2005-12-09 10:46  Zendy  阅读(4651)  评论(8编辑  收藏  举报