首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> .NET 實例教學

ASP.NET 頁面間傳值利器:Server.Transfer + Context.Handler 強型別存取上一頁面

     編輯:.NET 實例教學

傳統頁面傳值方式比較

方式優點缺點適用場景
QueryString簡單、可書籤長度限制、明文、不適合複雜物件簡單導航、分頁參數
Session容量大、跨頁面需手動清理、佔用伺服器記憶體、Web Farm 需共享 Session購物車、使用者狀態
POST 表單大量資料ASP.NET Web Forms 預設 PostBack 自己,跨頁 Post 需特殊處理表單提交
Server.Transfer伺服端轉向、URL 不變、可存取前頁面所有 public 成員僅限同一應用程式、瀏覽器歷史記錄不更新多步驟精靈、查詢/報表分離

核心技巧:Context.Handler 強型別轉換

Server.Transfer("Target.aspx") 執行後,目標頁面的 Context.Handler 指向 來源頁面實例 (前提:來源頁面尚未釋放,即首次載入非 PostBack)。將其轉換為具體頁面類型或介面,即可直接存取 public 屬性/方法。

基本範例:查詢頁 → 結果頁

1. 來源頁面 (QueryPage.aspx.cs) 定義公共屬性


public partial class QueryPage : System.Web.UI.Page
{
    protected TextBox txtStaDate, txtEndDate;

    // 公開唯讀屬性,封裝控制項存取
    public string StaDate => txtStaDate.Text;
    public string EndDate => txtEndDate.Text;

    protected void btnSearch_Click(object sender, EventArgs e)
    {
        Server.Transfer("ResultPage.aspx"); // 不帶 QueryString
    }
}

2. 目標頁面 (ResultPage.aspx.cs) 取得資料


public partial class ResultPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack) // 關鍵:只有首次 Transfer 時 Handler 是上一頁
        {
            // 強制轉換為具體類型
            QueryPage prev = Context.Handler as QueryPage;
            if (prev != null)
            {
                lblStaDate.Text = prev.StaDate;
                lblEndDate.Text = prev.EndDate;
                // 甚至可呼叫方法:var ds = prev.GetData(); GridView1.DataSource = ds; GridView1.DataBind();
            }
        }
    }
}

進階:多個查詢頁共用一個結果頁 — 介面多型

若有 QueryPage1、QueryPage2 都要導向 ResultPage,定義共同介面:

1. 參數承載類別


public class QueryParams
{
    public string StaDate { get; set; }
    public string EndDate { get; set; }
    // 可擴充更多欄位
}

2. 介面定義


public interface IQueryParams
{
    QueryParams Parameters { get; }
}

3. 各查詢頁實作介面


public partial class QueryPage1 : Page, IQueryParams
{
    private QueryParams _params = new QueryParams();
    public QueryParams Parameters => _params;

    protected void btnSearch_Click(object sender, EventArgs e)
    {
        _params.StaDate = txtStaDate.Text;
        _params.EndDate = txtEndDate.Text;
        Server.Transfer("ResultPage.aspx");
    }
}

// QueryPage2 同理...

4. 結果頁透過介面存取


protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack && Context.Handler is IQueryParams provider)
    {
        var p = provider.Parameters;
        lblStaDate.Text = p.StaDate;
        lblEndDate.Text = p.EndDate;
    }
}

關鍵限制與注意事項

  1. 僅首次載入有效:IsPostBack == false 時 Context.Handler 才是上一頁。PostBack 時變成自己,轉型會失敗或取到錯誤實例。
  2. 同一應用程式域:Server.Transfer 不跨應用程式 (虛擬目錄)。跨應用請用 Response.Redirect + Session/資料庫。
  3. 保留表單/查詢字串:Server.Transfer("Target.aspx", true) 第二參數 preserveForm=true 可讓目標頁面讀取 Request.Form 與 Request.QueryString。
  4. 生命週期:來源頁面 Page_Load → 事件處理 → Server.Transfer → 目標頁面 Page_Load → 目標頁面渲染 → 來源頁面 Page_Unload。來源頁面實例在目標頁面渲染期間仍存活。
  5. 型別安全:使用 as 或 is 防止 InvalidCastException。

實戰模式:精靈步驟共享資料物件


// Step1.aspx
public class WizardData { public string UserName; public int Age; }
public WizardData Data = new WizardData();
protected void btnNext_Click() { Server.Transfer("Step2.aspx"); }

// Step2.aspx
protected void Page_Load() {
    if (!IsPostBack) {
        var step1 = Context.Handler as Step1;
        if (step1 != null) {
            Session["WizardData"] = step1.Data; // 後續步驟改用 Session
        }
    }
}

結語

Server.Transfer + Context.Handler 是 ASP.NET Web Forms 獨有的強型別頁面間通訊機制,避免了 Session 的儲存/清理煩瑣、QueryString 的長度與安全限制。善用介面多型可實現多對一頁面流程,代碼清晰、編譯期型別安全、效能優異 (無序列化開銷)。雖然 Web Forms 漸被 MVC/Razor Pages 取代,但在維護既有專案時仍是不可或缺的利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved