萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> ASP.NET 程式設計

ASP.NET 網頁間參數傳遞:POST 與 GET 完整實作與安全性考量

前言

ASP.NET Web Forms 中頁面間傳值主要分為 GET (QueryString) 與 POST (表單回傳/跨頁回傳) 兩大類。本文詳細說明兩種方式的實作細節、優缺點比較、安全性風險與現代最佳實務。

一、GET 方式:QueryString (查詢字串)

1. 基本實作:Response.Redirect 帶參數

// 來源頁面
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);
}

2. 基本實作:HyperLink 控制項

<asp:HyperLink ID="hlkDetail" runat="server" 
    NavigateUrl='<%# "Detail.aspx?id=" + Eval("Id") + "&type=" + Eval("Type") %>'>
    檢視詳情
</asp:HyperLink>

3. 目標頁面接收

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");
    }
}

GET 優缺點總結

優點缺點
實作簡單、直觀參數暴露在 URL,可被竄改、書籤洩露敏感資訊
支援書籤分享、瀏覽器前進後退URL 長度限制 (~2KB),不適合大量資料
有利 SEO (搜尋引擎可索引參數化頁面)無法傳遞複雜物件、二進位資料
無伺服器端狀態佔用不安全:CSRF、XSS、SQL Injection 風險需額外防護

二、POST 方式:表單回傳

1. 同頁回傳 (PostBack) - 最常見

<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; // 直接存取控制項值
    // 處理邏輯...
}

2. 跨頁面 POST (PostBackUrl) - ASP.NET 2.0+

來源頁面:

<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 驗證錯誤。

3. 手動 Form POST 到其他頁面 (傳統 ASP 風格)

<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 中使用。

三、安全性最佳實務

1. 防止 CSRF (跨站請求偽造)

  • 所有 POST 表單加入 `` 儲存 Anti-CSRF Token,或使用 ASP.NET 內建 `ViewStateUserKey`。
  • Master Page 統一加入:`Page.ViewStateUserKey = Session.SessionID;`

2. 輸入驗證與清理

// 白名單驗證
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

3. 敏感資料不可放 QueryString

  • 帳號、密碼、身分證、Token、權限代碼 → 必須用 Session、TempData、加密 Token 或 POST。
  • 若必須用 URL 傳遞 ID,請使用無意義的 GUID 或加密後的 Token,避免連續 ID 遭枚舉攻擊。

四、現代架構建議:PRG 模式 (Post-Redirect-Get)

表單送出 (POST) → 後端處理 → **重導向 (GET)** 到結果頁。優點:

  • 防止使用者重新整理重複提交。
  • 結果頁可書籤、分享 (URL 乾淨)。
  • 符合 REST 風格。
// 來源頁面 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` 攜帶必要參數。永遠記得:驗證所有輸入、編碼所有輸出、最小權限原則。

copyright © 萬盛學電腦網 all rights reserved