首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET Page_Load 執行兩次問題根因與解決方案

     編輯:ASP.NET 基礎

現象

頁面載入時 Page_Load 被呼叫兩次,導致資料重複查詢、初始化邏輯重跑、ViewState 異常等。

根本原因

@Page 指示詞缺少 AutoEventWireup="false",或顯式設為 true(預設值)。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApp.Default" %>

當 AutoEventWireup="true" 時,ASP.NET 執行階段會自動依命名慣例 (Page_Load, Page_Init 等) 將方法掛接到對應生命週期事件。
若程式碼後置 (CodeBehind) 中同時在 InitializeComponent 或建構式中手動掛接事件:

this.Load += new EventHandler(Page_Load); // 手動掛接

則會造成雙重訂閱:自動一次 + 手動一次 → Page_Load 執行兩次。

解決方案(二選一)

方案 A:關閉自動掛接(推薦,Microsoft 最佳實踐)

<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Default.aspx.cs" Inherits="WebApp.Default" %>

並在 InitializeComponent 或建構式中保留手動掛接:

private void InitializeComponent()
{
    this.Load += new EventHandler(Page_Load);
    this.Init += new EventHandler(Page_Init);
}

優點:明確控制事件訂閱、效能微幅提升、避免命名慣例衝突。

方案 B:保持自動掛接,移除手動掛接代碼

刪除 InitializeComponent 中的 this.Load += ... 等手動訂閱行,完全依賴命名慣例。

缺點:若方法命名不符慣例 (如 MyLoad) 則不會自動掛接;重構時易忘記。

驗證方法

protected void Page_Load(object sender, EventArgs e)
{
    System.Diagnostics.Debug.WriteLine("Page_Load 執行 " + DateTime.Now.Ticks);
    // 輸出視窗應只出現一次
}

延伸:其他常見雙重執行原因

原因現象排查
Master Page 也有 Page_Load母版頁與內容頁各執行一次正常生命週期,非重複
UpdatePanel 觸發部分回傳非同步請求也會跑 Page_Load檢查 IsPostBack、ScriptManager.IsInAsyncPostBack
Response.Redirect 同頁導向完整生命週期跑兩次改用 Server.Transfer 或避免導向
HttpModule 重寫路徑攔截器導致雙重處理檢查模組邏輯

結語

AutoEventWireup="false" + 手動掛接 是 WebForms 專案的標準配置,能徹底杜絕 Page_Load 雙重執行,並符合 Microsoft 官方建議。新專案請從專案範本層面固定此設定。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved