首先,請理解什麼是 wrapper page。
wrapper page 是我定義的一種專門用來封裝使用者控制項 ascx 的 webform,wrapper page 的 Render 方法被重寫(override),僅 render 它的 UserControl 成員。這樣,我們就可以通過 ascx 輸出乾淨的 html 片斷。是的,我們的目標就是輸出乾淨的 html 片斷!
--------------------------------------------------------------------------------
實現方法
目標明確了,思路有了,現在讓我們來實現吧~
很簡單:寫一個 Wrapper Page Base,作為所有 wrapper page 的基類,以後的 wrapper page 都從它繼承。這個類(WrapperPageBasel類)繼承自System.Web.UI.Page類,他只要做兩件事情:
擁有一個 UserControl 成員
重寫父類(Page)的 Render 方法
那麼我們在重寫的 Render 方法裡執行 UserControl 的 Render 方法即可。請看代碼1):
/// <summary>
/// Ajax封裝頁面基類
/// </summary>
public class WrapperPageBase : System.Web.UI.Page
{
public UserControl control { get; set; }
protected override void Render(HtmlTextWriter writer)
{
if (control == null)
control = (UserControl)this.LoadControl("~/Controls/dummy.ascx"); // 一個dummy,null時輸出server error..之類的資訊
control.RenderControl(writer);
}
}Wrapper Page繼承自WrapperPageBase類:
public partial class Ajax_Test : WrapperPageBase
{
protected void Page_Load(object sender, EventArgs e)
{
this.control = (UserControl)this.LoadControl("~/Controls/any.ascx"); // 有用的使用者控制項
}
}在頁面中,使用jQuery非同步呼叫。參看ashx + jQuery, a lightly ajax solution of asp.net 的執行個體。
你的頁面只需要一句話:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Test.aspx.cs" Inherits="Ajax_Test" %>其餘都可以刪除。——當然,你也可以不刪除,你會發現哪些代碼不會出現在頁面上。你還可以在同一個 Wrapper Page 裡來切換 UserControl,只要判斷下query string,像這樣:
protected void Page_Load(object sender, EventArgs e)
{
var str = Request["Want"];
if(str == "IWantA")
this.control = (UserControl)this.LoadControl("~/Controls/A.ascx"); // 使用者控制項A
else if(str == "IWantB")
this.control = (UserControl)this.LoadControl("~/Controls/B.ascx"); // 使用者控制項A
else
this.control = (UserControl)this.LoadControl("~/Controls/WhatDoYouWant.ascx"); // 使用者控制項WhatDoYouWant
}至此,這個解決方案就完成了。
--------------------------------------------------------------------------------
為什麼要這麼做?
事實上,我們不用 WrapperPageBase,不用重寫 Render 方法,簡單地把 webform 裡的 html 代碼全部刪掉,再換上我們現在放在 ascx 裡的代碼,這樣也可以達到輸出 html 片斷的效果。但是為什麼要這麼麻煩????
理由如下:
你不用刪除 webform 裡的那些代碼
你可以不用修改,使用現成的 ascx
機制是透明的,你只需要 LoadControl
最後,你完全可以在同一個 webfrom 雷根據不同的 query string 來輸出不同的 html 片斷 —— 哪怕這些片斷毫不相干!神奇吧!
1) 代碼裡指定了一個 dummy,當 dummy.ascx 的內容為空白,或者不指定 dummy 時,HtmlTextWriter 會顯示一個沒有內容但是完整的 html 頁面,它不是我們要的 html 片斷