小技巧:基于ASP.NET的網(wǎng)頁復用方法
2024-07-10 13:04:37
供稿:網(wǎng)友
 
  0、 引言
  隨著網(wǎng)絡的不斷發(fā)展,以web為基礎的b/s架構是當前應用程序的主流,在這種架構下業(yè)務邏輯和數(shù)據(jù)庫都放在服務器段,用戶通過瀏覽器來操作服務器端的數(shù)據(jù)。在microsoft.net平臺還沒有推出之前,人們可以通過asp方式實現(xiàn)上述目標,現(xiàn)在則可以選擇asp.net了。
  
  asp.net 是一個已編譯的、基于.net的環(huán)境,可以用任何與.net兼容的語言(包括 visual basic.net、c#和jscript.net.)創(chuàng)作應用程序。任何asp.net 應用程序都可以使用整個.net framework。相比之下,asp是一種解釋型的編程框架,腳本語言為vbscript和javascript,這兩種語言的功能有限,需要使用c++、java等語言編寫的組件來擴展其功能,加之又是解釋運行,效率有限。
  
  1、 問題提出
  一個網(wǎng)站,特別是與數(shù)據(jù)庫結合起來的網(wǎng)站(如新聞網(wǎng)站、產(chǎn)品介紹網(wǎng)站等),有許多網(wǎng)頁都是類似的,不同的只是與數(shù)據(jù)庫相關的數(shù)據(jù)(如不同的新聞內容、不同的產(chǎn)品等)。我們沒有必要為每一個頁面寫一個文件,這樣做的代價太高,我們可以將不變的部分固定下來,變化的部分根據(jù)客戶端請求的不同而動態(tài)產(chǎn)生。
  
  以一個包含頁眉、頁腳、導航欄的新聞網(wǎng)站頁面為例,示例頁面如下:
  
  2、 解決方法
  asp.net中引入了web窗體用戶控件的概念,利用它我們可以方便地創(chuàng)建自定義的可重用控件。用戶控件可以在第一次請求時被編譯并存儲在服務器內存中,這樣可以縮短后續(xù)請求的響應時間。用戶控件繼承自system.web.ui.usercontrol。我們可以將頁眉、頁腳、導航欄都做成用戶控件。
  
  為簡單起見,頁眉只包含一張指向首頁的圖片。新建文件header.ascx,內容如下:
  
  <%@ control %>
  
  <table width="775" border="0">
  
  <tr>
  
  <td align="center" valign="middle"><a href="../default.aspx"><img alt="" src="http://m.survivalescaperooms.com/htmldata/2006-04-04/upload/200902/banner1.jpg" border="0"></a>
  
  </td>
  
  </tr>
  
  </table>
  
  頁腳為兩行文字,用兩行一列的表格實現(xiàn)。新建文件footer.ascx,內容如下:
  
  <%@ control %>
  
  <table width="775" border="0">
  
  <tr>
  
  <td align="center" valign="middle">www.hahaha.com</td>
  
  </tr>
  
  <tr>
  
  <td align="center" valign="middle">hahaha studio </td>
  
  </tr>
  
  <tr>
  
  <td align="center" valign="middle">contact us :<a href="mailto:[email protected]">[email protected]</a> </td>
  
  </tr>
  
  </table>
  
  導航菜單有5個鏈接,分別對應校園、學術報告、時事、體育、科教五個欄目,對應鏈接為campus.aspx、dissertation.aspx、news.aspx、sports.aspx、education.aspx,所采用的是圖片鏈接的方式。建立menu.ascx文件,其代碼與頁眉相似,此處略去。
  
  三個控件的效果如圖1。
  
  我們在campus.aspx等五個文件中均可用到上述控件,以compus.aspx為例。首先在文件的開始加入語句<%@ register tagprefix="uc1" tagname="header" src="controls/header.ascx" %>注冊控件,該語句注冊的是頁眉控件,同樣注冊頁腳和導航菜單控件;然后在需要使用的網(wǎng)頁位置,用語句<uc1:header id="header1" runat="server"></uc1:header>加入以上注冊的控件,就可以了。還可以直接在visual studio.net開發(fā)環(huán)境中將web窗體用戶控件拖放至需要的位置,查看網(wǎng)頁代碼可知,兩種方法的效果是一樣的。開發(fā)環(huán)境中的圖片如圖2。
  
  但是,每個頁面都要手動加上上段所提代碼,似乎有些麻煩,是否可以設定一個基類,而具體網(wǎng)頁作為子類來繼承它呢,事實證明是可行的,這也是asp.net帶來的好處之一。
  
  建立文件univnewsbase.cs,代碼如下:
  
  using system;
  
  using system.io;
  
  using system.web.ui;
  
  using system.web.ui.htmlcontrols;
  
  using univnews.controls;
  
  namespace univnewsbase
  
  {
  
  public class univnewsbase : system.web.ui.page
  
  {
  
  protected override void render(htmltextwriter writer)
  
  {
  
  //建立頁眉,導航菜單,頁腳三個控件
  
  header header = (header)loadcontrol(request.applicationpath +
  
  path.altdirectoryseparatorchar +
  
  "controls/header.ascx");
  
  menu menu = (menu)loadcontrol(request.applicationpath +
  
  path.altdirectoryseparatorchar +
  
  "controls/menu.ascx");
  
  footer footer = (footer)loadcontrol(request.applicationpath +
  
  path.altdirectoryseparatorchar +
  
  "controls/footer.ascx");
  
  //得到網(wǎng)頁中的form,將上面建立的控件插入
  
  control form = page.controls[1];
  
  form.controls.addat(0, header);
  
  form.controls.addat(1, menu);
  
  form.controls.addat(page.controls[1].controls.count, footer);
  
  //回調父類方法
  
  base.render(writer);
  
  }
  
  }
  
  }
  
  代碼中使用loadcontrol方法得到載入已定義好的web用戶控件,再強制轉換為相應的類型。page.controls[1]得到網(wǎng)頁的form,再用form的controls屬性的addat方法加控件到form中。值得注意的是在加頁腳控件footer時,使用了page.controls[1].controls.count來定位,這樣可以確保頁腳控件在form上的最后一個位置。
  
  刪去campus.aspx文件中的web窗體用戶控件,在campus.aspx.cs中將campus類的基類由system.web.ui.page改為univnewsbase,其余保持不變,可以發(fā)現(xiàn)運行時的結果和修改前一樣。而其它的頁面,凡是采用和campus.aspx一樣布局的,都可以從univnewsbase繼承。如此,這些頁面的制作工作被大大簡化,并且布局若要有所改變,修改基類就可以了,這充分利用了面向對象方法的優(yōu)點。
  
  3、 擴展
  上述解決方案針對橫向導航菜單,但是現(xiàn)在有許多情況下導航菜單是豎向排列,位于頁面左邊(如圖3),這時就不能使用上面的方法了。一般地,需要做一個基本頁面的框架(并不是html中frame的概念),把頁眉、頁腳、導航菜單都放好后,再在導航菜單的右側,也就是根據(jù)頁面不同而不同的內容部分,放上諸如placeholder、datalist等等服務器端控件,然后在頁面所對應的codebehind文件中,對這些控件應該包含的數(shù)據(jù)加以操作,例如從數(shù)據(jù)庫中將新聞標題綁定到datalist上,或著將具體新聞顯示出來等等。以這種方式,頁面文件(.aspx)同樣可以做到盡可能少,其余事務均放在服務器端處理了。