2016-10-06 79 views
0

我在調用一些已經通過jQuery ajax使用[WebMethod]裝飾的方法。ASPX頁面調用[WebMethod]時的生命週期s

這些需要在外部庫中設置數據庫連接,該連接對於每種方法都是相同的。

我原來的代碼是這樣的:

public partial class Server : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 
     // code to set up DB connections 
     ExternalLibrary.SetupDB(); 
    } 

    [WebMethod] 
    public static string AjaxAccessibleMethod() 
    { 
     try 
     { 
      // get some data from the database via the external library 
      ExternalLibrary.CallDatabase(); 
     } 
     catch(Exception ex) 
     { 
      // handle errors 
     } 
    } 
} 

這是工作,但隨後開始拋出異常,聲稱ExternalLibrary的數據庫尚未初始化。

在我的代碼中放置斷點我發現在調用我的AjaxAccessibleMethod時沒有調用Page_Load事件,我也嘗試將DB安裝的東西移動到Page_Init事件中,但同樣沒有調用。

任何人都可以向我解釋使用WebMethods時的aspx頁面生命週期嗎?事實上,這起作用最初似乎意味着Page_Load被稱爲,但它不再是。

+1

http://stackoverflow.com/a/18072090/885626 – Ric

回答

5

請注意,您作爲WebMethod使用的方法是靜態的,這應該是第一個暗示Page對象沒有被創建的事實的暗示。方法是一種完全成熟的Web服務的簡單替代方法,因此,它的生命週期與Web服務相比更接近頁面。也就是說,請求通過一般的ASP.NET管道,像HttpContext,Request等對象。但是接下來會發生不同:對於頁面請求和回發頁面對象被創建並且發生整個頁面事件系列,而頁面方法不創建頁面對象,並且方法簡單地被稱爲Server.AjaxAccessibleMethod()

實際上沒有辦法將兩者混合,因爲這會不必要地使對頁面方法的調用處理複雜化。所以,着你的唯一路徑這裏是重複的必要代碼:

protected void Page_Load(object sender, EventArgs e) 
{ 
    // code to set up DB connections 
    ExternalLibrary.SetupDB(); 
} 

[WebMethod] 
public static string AjaxAccessibleMethod() 
{ 
    ExternalLibrary.SetupDB(); 
    ... 
} 
+0

如何添加「ExternalLibrary.SetupDB();」在靜態構造函數中? 這樣我認爲可以避免代碼重複。 – Boney

+0

@Boney,我不會推薦使用靜態構造函數。這裏的問題是,你完全無法控制它何時被調用。所以OP的需求可能會發生得太早。此外,當前的代碼每次請求調用一次,至少在頁面方法的情況下,你不能確定這將發生在靜態c'tor – Andrei

+0

謝謝安德烈,你說的是什麼意思。但它仍然讓我撓頭,爲什麼這個工作......而且令我擔心的是,我在其他地方使用過這種模式(它有效) - 是否有任何機制讓您意識到這可能會導致這種情況發生,例如調用頁面(而不是[WebMethod]),然後調用[WebMethod]? – Morvael