Response.Redirect(url) 預設 endResponse = true,內部呼叫 Thread.CurrentThread.Abort() 拋出 ThreadAbortException 強制終止執行緒。高併發下大量拋棄執行緒會耗盡執行緒池,導致網站回應緩慢甚至停擺。
endResponse = falseResponse.Redirect("Target.aspx", false);
但此時頁面生命週期繼續執行,後續事件(如 btnSave_Click)仍會觸發,造成安全隱患與邏輯錯誤。
RedirectUser 擴充方法public static class HttpResponseExtensions
{
public static void RedirectUser(this HttpResponse response, string url)
{
if (response.IsRequestBeingRedirected) return; // 避免重複導向
response.Redirect(url, false); // 不中止執行緒
var context = HttpContext.Current;
if (context != null)
{
context.ApplicationInstance.CompleteRequest(); // 優雅完成請求,執行管線事件但跳過頁面生命週期
}
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!User.HasPermission)
{
Response.RedirectUser("Unauthorized.aspx");
return; // 雖然 CompleteRequest 會跳過後續頁面事件,仍建議早期返回
}
}
protected void btnSave_Click(object sender, EventArgs e)
{
if (Response.IsRequestBeingRedirected) return; // 防禦性檢查
// 存檔邏輯...
}
<form id="form1" runat="server">
<% if (!Response.IsRequestBeingRedirected) { %>
<asp:Button ID="btnSave" runat="server" Text="儲存" OnClick="btnSave_Click" />
<!-- 其他控件 -->
<% } %>
</form>
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
if (Response.IsRequestBeingRedirected)
{
e.Cancel = true;
return;
}
// 正常編輯邏輯...
}
| 方案 | 優點 | 缺點 |
|---|---|---|
Redirect(true) | 簡單、立即停止 | 拋棄執行緒、擴展性差 |
Redirect(false) | 不拋棄執行緒 | 頁面繼續執行、需手動防護 |
RedirectUser | 不拋棄執行緒、自動完成請求、防重複導向 | 需在關鍵事件加檢查 |
高併發 Web Forms 應用、長時間運行請求、需嚴格控制導向流程的安全敏感頁面。