| 方式 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|
| 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 屬性/方法。
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
}
}
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,定義共同介面:
public class QueryParams
{
public string StaDate { get; set; }
public string EndDate { get; set; }
// 可擴充更多欄位
}
public interface IQueryParams
{
QueryParams Parameters { get; }
}
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 同理...
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;
}
}
IsPostBack == false 時 Context.Handler 才是上一頁。PostBack 時變成自己,轉型會失敗或取到錯誤實例。Server.Transfer 不跨應用程式 (虛擬目錄)。跨應用請用 Response.Redirect + Session/資料庫。Server.Transfer("Target.aspx", true) 第二參數 preserveForm=true 可讓目標頁面讀取 Request.Form 與 Request.QueryString。Page_Load → 事件處理 → Server.Transfer → 目標頁面 Page_Load → 目標頁面渲染 → 來源頁面 Page_Unload。來源頁面實例在目標頁面渲染期間仍存活。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 取代,但在維護既有專案時仍是不可或缺的利器。