傳統 Response.Redirect 或 `history.back()` 導致查詢條件、捲軸位置、分頁狀態遺失。本文比較四種保持狀態回傳方案:Server.Transfer + PreviousPage、HttpContext.Current.Handler 型別轉換、Session/ViewState、URL 參數,並給出實作代碼與優缺點分析。
| 方案 | 原理 | 優點 | 缺點 |
|---|---|---|---|
| Server.Transfer + PreviousPage | 伺服器端轉移,保留前一頁物件實例 | 無網路往返、直接存取前頁控制項/屬性 | URL 不變、瀏覽器歷史無記錄、需啟用 EnableViewStateMac |
| HttpContext.Current.Handler | 當前處理常式即前一頁實例 | 不需 Transfer,適用 Redirect 後回傳 | 型別轉換需知前頁具體類型、跨應用程式失效 |
| Session/ViewState | 伺服器/客戶端儲存狀態 | 通用、支援跨頁面 | Session 消耗記憶體、ViewState 增加頻寬 |
| URL 參數 (QueryString) | 狀態序列化為 URL | 可書籤、可分享、無伺服器狀態 | 長度限制、敏感資料洩漏、需手動編碼/解碼 |
// Search.aspx 查詢頁
public partial class Search : Page
{
public string SqlWhere { get; set; } // 供結果頁讀取
protected void btnSearch_Click(object sender, EventArgs e)
{
SqlWhere = BuildWhereClause(); // 組裝查詢條件
Server.Transfer("Result.aspx"); // 伺服器端轉移
}
}
// Result.aspx 結果頁
public partial class Result : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack && PreviousPage is Search search)
{
string sql = search.SqlWhere;
LoadGrid(sql); // 直接使用前頁屬性查詢
}
}
protected void btnBack_Click(object sender, EventArgs e)
{
Server.Transfer("Search.aspx"); // 返回查詢頁,狀態完整保留
}
}
// Search.aspx
public partial class Search : Page
{
public string DateTimeValue { get; set; }
protected void btnGo_Click(object sender, EventArgs e)
{
DateTimeValue = txtDate.Text;
Response.Redirect("Detail.aspx"); // 真正 Redirect
}
}
// Detail.aspx
public partial class Detail : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack && HttpContext.Current.Handler is Search search)
{
hiddenField.Value = search.DateTimeValue; // 取得前頁屬性
}
}
protected void btnBack_Click(object sender, EventArgs e)
{
Response.Redirect("Search.aspx"); // 回傳,但 Search 會重新初始化
}
}
if (PreviousPage != null)
{
var cp = (ContentPlaceHolder)PreviousPage.Master.FindControl("UIContentAreaPlaceHolder");
if (cp != null)
{
var hf = (HiddenField)cp.FindControl("hfSql");
if (hf != null) this.hfSql.Value = hf.Value;
}
}
LoadGrid(this.hfSql.Value);