ASP.NET Web Forms 中頁面間傳值主要分為 GET (QueryString) 與 POST (表單回傳/跨頁回傳) 兩大類。本文詳細說明兩種方式的實作細節、優缺點比較、安全性風險與現代最佳實務。
// 來源頁面
protected void btnGo_Click(object sender, EventArgs e)
{
string url = $"Result.aspx?name={Server.UrlEncode(txtName.Text)}&email={Server.UrlEncode(txtEmail.Text)}";
Response.Redirect(url);
}
<asp:HyperLink ID="hlkDetail" runat="server"
NavigateUrl='<%# "Detail.aspx?id=" + Eval("Id") + "&type=" + Eval("Type") %>'>
檢視詳情
</asp:HyperLink>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string name = Request.QueryString["name"]; // 自動 URL 解碼
string email = Request.QueryString["email"];
// 建議驗證與清理
if (string.IsNullOrWhiteSpace(name)) Response.Redirect("Error.aspx");
}
}
| 優點 | 缺點 |
|---|---|
| 實作簡單、直觀 | 參數暴露在 URL,可被竄改、書籤洩露敏感資訊 |
| 支援書籤分享、瀏覽器前進後退 | URL 長度限制 (~2KB),不適合大量資料 |
| 有利 SEO (搜尋引擎可索引參數化頁面) | 無法傳遞複雜物件、二進位資料 |
| 無伺服器端狀態佔用 | 不安全:CSRF、XSS、SQL Injection 風險需額外防護 |
<form id="form1" runat="server">
<asp:TextBox ID="txtInput" runat="server" />
<asp:Button ID="btnSubmit" runat="server" Text="送出" OnClick="btnSubmit_Click" />
</form>
// 後台
protected void btnSubmit_Click(object sender, EventArgs e)
{
string value = txtInput.Text; // 直接存取控制項值
// 處理邏輯...
}
來源頁面:
<asp:TextBox ID="txtUser" runat="server" />
<asp:Button ID="btnSend" runat="server" Text="送往處理頁" PostBackUrl="~/Process.aspx" />
目標頁面 (Process.aspx):
<%@ PreviousPageType VirtualPath="~/SourcePage.aspx" %> // 強型別存取 (需來源頁面定義 public 屬性)
protected void Page_Load(object sender, EventArgs e)
{
if (PreviousPage != null && PreviousPage.IsCrossPagePostBack)
{
// 方式一:強型別屬性 (推薦)
string user = PreviousPage.UserName; // 來源頁面需 public string UserName { get { return txtUser.Text; } }
// 方式二:FindControl (不需 PreviousPageType)
// TextBox txt = (TextBox)PreviousPage.FindControl("txtUser");
// string user = txt?.Text;
}
}
注意:跨頁回傳會觸發來源頁面完整生命週期 (含 ViewState 驗證),目標頁面需設定 `<%@ Page EnableViewStateMac="false" %>` 或確保兩頁面共用同一 `machineKey`,否則會拋出 ViewState 驗證錯誤。
<form id="form1" runat="server" action="Receive.aspx" method="post">
<input type="text" name="username" />
<input type="submit" value="送出" />
</form>
// Receive.aspx 後台
string username = Request.Form["username"]; // 注意:原文寫錯 Request.Form["receive"]
缺點:繞過 ASP.NET ViewState 機制,失去控制項狀態管理優勢,不建議在 Web Forms 中使用。
// 白名單驗證
string name = Request.QueryString["name"];
if (!Regex.IsMatch(name, @"^[\u4e00-\u9fa5a-zA-Z0-9]{1,20}$"))
throw new ArgumentException("姓名格式錯誤");
// HTML 編碼輸出防 XSS
lblName.Text = Server.HtmlEncode(name); // 或 HttpUtility.HtmlEncode
表單送出 (POST) → 後端處理 → **重導向 (GET)** 到結果頁。優點:
// 來源頁面 POST 處理
protected void btnSubmit_Click(object sender, EventArgs e)
{
// 1. 驗證輸入
// 2. 儲存資料
// 3. 將必要參數存入 TempData (ASP.NET Core) 或 Session (Web Forms)
Session["SuccessMsg"] = "資料已新增";
Session["NewId"] = newId;
// 4. 重導向到結果頁 (GET)
Response.Redirect($"Result.aspx?id={newId}");
}
// 結果頁面 GET 載入
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string id = Request.QueryString["id"];
// 讀取資料顯示
if (Session["SuccessMsg"] != null)
{
lblMsg.Text = Session["SuccessMsg"].ToString();
Session.Remove("SuccessMsg");
}
}
}
總結:ASP.NET 網頁傳值核心原則:查詢/導航用 GET (QueryString)、表單提交/狀態變更用 POST、敏感資料用 Session/TempData/加密 Token、採用 PRG 模式避免重複提交。避免直接 `Form.Action` 跨頁 POST,善用 `PostBackUrl` 搭配 `PreviousPageType` 或單純 `Response.Redirect` 攜帶必要參數。永遠記得:驗證所有輸入、編碼所有輸出、最小權限原則。