ASP.NET 中的设计模式之MVC篇-3

来源:互联网 发布:学计算机编程有前途吗 编辑:程序博客网 时间:2024/05/21 08:52
 <%@ Control Language="c#" AutoEventWireup="false" Codebehind="Template1.ascx.cs" Inherits="M161.CS.Web.Award.Template1" TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<%@ Register TagName="AwardHeader" TagPrefix="CC" Src="AwardHeader.ascx" %>
<%@ Register TagName="AwardNav" TagPrefix="CC" Src="AwardNav.ascx" %>
<HTML><HEAD>
    
<LINK href="../default.css" type="text/css" rel="stylesheet">
</HEAD>
<body onload="javascript:onload();">
    
<form id="Form1" method="post" runat="server">
    
<div><CC:AwardHeader runat="server" ID="Header1" /></div>
    
<div style="WIDTH:100%">
    
<table width="100%" border="0" cellpadding="0" cellspacing="0" id="TableTemplate">
        
<tr>
        
<td style="width:150px">
        
<CC:AwardNav runat="server" ID="Awardnav1" />
        
</td>
        
<td valign="top" align=left>
    
<asp:PlaceHolder id="_placeHolder" runat="server"
EnableViewState
="False" />
        
</td>
        
</tr>
    
</table>
    
</div>
    
</form>
</body>
</HTML>

在这部分代码中,是将页面公共部分做成了控件,然后在模板中注册。尽管在每一个页面中注册一遍控件所需代码也不是很多,但通过模板维护公共部分有一个好处:可以更快速地改变整个应用程序的外观、布局、颜色等,也可以准备多个不同的模板,并为不同的页面选择其合适的模板。

Page基类
要采用模板来实现页面,除了要将模板的内容包含起来,往往还要在页面中替换或者填充模板中的一些内容。这些装载、转换工作既然也是每一个页面都要做的事情,当然也可以将它们放到一个单独的类中实现,这就是Page基类。

Page基类在ASP.NET中的角色是公共的控制器。我们可以将每一个页面都要实现的控制逻辑放到此处。

下面的代码文件是实现图2的Page基类。
using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace MyNameSpace
{
    /**//// <summary>
    ///系统各页面的BasePage
    /// 作用:通过装载模板为各个页面加载公共布局,包括Header、导航条、页脚
    /// </summary>
    public class MyBasePage:Page
    {
        PlaceHolder _container;
        string      _templatePath = "Template1.ascx";

        public MyBasePage()
        {
            _container = new PlaceHolder();
            _container.ID = "_container";
        }
       
        protected string TemplatePath
        {    //允许指定不同的模板文件
            get { return _templatePath; }
            set { _templatePath = value; }
        }

        protected override void OnInit(EventArgs e)
        {
            //装载模板文件
            Control template = LoadControl(_templatePath);
            if (template == null)
                throw new Exception("装载模板文件错误!");
            Control placeHolder =
                template.FindControl("_placeHolder");
            if (placeHolder == null)
                throw new Exception("模板文件格式错误");
            placeHolder.Controls.Add(_container);
            for (int i=0; i<template.Controls.Count; i++)
            {
                Control c = template.Controls[0];
                template.Controls.Remove(c);
                Controls.Add(c);
            }
              base.OnInit(e);
        }
    }
}
其它页面继承Page基类,而不是继承默认的System.Web.UI.Page类。
//page1.aspx.cs
public class page1 : MyBasePage
{
    //
}

<!—page1.aspx
<%@ Page Inherits="page1" CodeBehind="page1.aspx.cs" Language="c#" AutoEventWireup="false" %>
<h5>This is page1</h5>

公共的Page基类可以做很多事情,常见的如对错误(Exception)的处理、接收页面传递的字段、URL与字符集转换、增加客户端脚本等。

在性能方面,使用ACT测试的结果表明,使用Page基类和模板技术带来的性能损失非常有限。

最后,顺便提到一下笔者认为非常有意思的一点:在ASP.NET中,无论是模板、Page基类、还是独立的页面,都可以同时具有视图文件(.aspx文件)和代码文件(.cs文件)其中之一或者全部。例如,在微软资助出版的ESP(即.NET企业解决方案模式)书籍中,就提供了另外一种Page基类,该page基类的视图文件就是各个页面的公共视图,也相当于我们这里的模板文件。ASP.NET中这种灵活的机制既为大多数开发人员提供了方便,也同时增加了犯错的可能---尽管你可以用多种方式实现同样的功能,但最佳的方式是什么呢?正如我们已经找到了复用MVC三者中任何一种的方式,但对于MVC究竟是分离还是合并到一起,仍然需要根据应用程序的复杂程度等实际情况做出选择。