前言
在以前(或許現在),當我們在做WEB項目的時候,常常會用到一些共用檔案,比如整頁的頂部(頁首),左部(導航),底部(頁尾)等等一些共用的HTML,ASP等檔案,即便如此,我們也需要預先為這些檔案做好架構的樣式(一般是用table吧?!沒幾個會用DIV吧),以組合(include)這些檔案得到一個完整的頁面,這些共用檔案的組合,這裡假設把它定義成模板(儘管模板的真正含義可能遠不止此)。即便如此,當我們項目中整個架構發生變動時,我們不得修改原先通過table等等一些HTML標籤定義好的每個需要這樣模板的頁面,而這樣的工作儘管可以通過ctrl+c和ctrl+v來完成,但同時工作量也是巨大的,耗時的。
發展
在ASP.NET裡,使用的是物件導向的開發模式,可以這麼理解---每個頁面都是一個從SystemWeb.UI.Page繼承的Class,這個類給我們提供了一些諸如緩衝,表示,應答,請求等服務(說是方法也行)。通過物件導向的方法是不是有比用include更好的解決方案呢?當然,答案是肯定的。
實現
記得有句名言叫“任何問題都可以通過加入一個中介層來實現”,舉個很簡單的例子,我們常常使用Façade這個模式降低系統的耦合度,而我們又為什麼要使用設計模式呢?主要是用來減小耦合提高複用的。
從所有的ASPX頁面都由SystemWeb.UI.Page繼承而來這點上來看,我們只需在ASPX和SystemWeb.UI.Page之間加入一層,寫一個我們自己的Class就可以使問題變得簡單化,而在.NET架構中,允許使用者自訂HTML代碼(這點可以參考Web User Controls),這樣解決問題的雛形就出來了,見。
圖中的“自訂類”就相當於我們加入的一個中介層,該自定類繼承System.Web.UI.Page這個基類,下面給出自定類的代碼:
PageBase.cs
程式碼: public class PageBase:System.Web.UI.Page
{
public string PageTitle="測試模板";
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
writer.Write(@"<html><head>
<meta http-equiv='Content-Type' content='text/html; charset=gb2312'>
<title>" + this.PageTitle + "</title></head>");
writer.Write(@"<body>
<table border='0' width='680'>
<tr>
<td width='160' bgcolor='#006699' align='center'><font color='#FFFFFF'><b><a href='index.aspx'>首頁</a></b></font></td>
<td colspan='2' width='520'>廣告條</td>
</tr>
<tr>
<td width='160' valign='top'>
<p>導航</p>
<p><a href='newContact.aspx'>新增連絡人...</a></p>
<p>尋找連絡人</p>
</td>
<td width='10'> </td>
<td width='510'>
");
base.Render(writer);
writer.Write(@"</td></tr><tr><td width='100%' colspan='3'>頁尾 </td></tr></table></body></html>");
}
}
上面的PageBase.cs就是我們的自定類,這樣,我們在其他ASPX頁面中就可以直接繼承PageBase這個類,而非System.Web.UI.Page,下面分別是index.aspx和newContact.aspx的代碼(分別包含index.aspx.cs和newContact.aspx.cs):
Index.aspx
程式碼:<%@ Page language="c#" Codebehind="index.aspx.cs" AutoEventWireup="false" Inherits="wab.index" %>
<form id="index" method="post" runat="server">
<aspataGrid id="contacts" runat="server" Width="492px" Height="104px"></aspataGrid>
</form>
index.aspx.cs(繼承自訂類PageBase)
程式碼: public class index : PageBase
{
protected System.Web.UI.WebControls.DataGrid contacts;
private void Page_Load(object sender, System.EventArgs e)
{
// 在此處放置使用者代碼以初始化頁面
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN:該調用是 ASP.NET Web 表單設計器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 設計器支援所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
newContact.aspx
程式碼:<%@ Page language="c#" Codebehind="newContact.aspx.cs" AutoEventWireup="false" Inherits="wab.newContact" %>
<form id="newContact" method="post" runat="server">
<P><FONT face="宋體">名子</FONT>
<asp:TextBox id="TextBox1" runat="server"></asp:TextBox></P>
<P><FONT face="宋體">姓氏</FONT>
<asp:TextBox id="TextBox2" runat="server"></asp:TextBox></P>
<P>
<asp:Button id="Button1" runat="server" Text="Button"></asp:Button></P>
</form>
newContact.aspx.cs(繼承自定類PageBase)
public class newContact : PageBase
{
protected System.Web.UI.WebControls.TextBox TextBox1;
protected System.Web.UI.WebControls.Button Button1;
protected System.Web.UI.WebControls.TextBox TextBox2;
private void Page_Load(object sender, System.EventArgs e)
{
}
#region Web Form Designer generated code
override protected void OnInit(EventArgs e)
{
//
// CODEGEN:該調用是 ASP.NET Web 表單設計器所必需的。
//
InitializeComponent();
base.OnInit(e);
}
/// <summary>
/// 設計器支援所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
this.Load += new System.EventHandler(this.Page_Load);
}
#endregion
}
以上就是ASP.NET中模板基本的實現方法,不過在此先聲明一點,這麼做會讓系統的效能下降一點點,但是這一點點並不影響實際項目,但我相信這一點點的系統效能換來的是日後維護的方便,相信很值得。
Windows 2000 server + Visual Studio.net(.NET Framework 1.0)下測試通過。