2009年11月16日星期一

ASP.NET使用Throw中止頁面

通常新接觸ASP.NET的朋友,都會把程式碼放進Page_Load事件中,如果因為不符合某條件而要中止網頁運行的話(例如一些要檢查登入的頁面),可能會用Exit Sub(VB)或者return(C#)退出Page_Load事件。

當然如果整個載入過程只有Page_Load的話,這個做法都還可以的。但假如還有其他Stage,例如Page_Init , Page_LoadComplete... (可參考ASP.NET Page Life Cycle Overview),單純地退出Page_Load事件就可以為你帶來一些程式上的錯誤。

當然概念上,大家要注意,即使你沒有寫上其他Stage的程式碼,但Runtime時,ASP.NET都會經過的,所以不要認為只把程式碼放進Page_Load事件中,便不會觸發其他Stage Event。

以下面段Code為例,網頁載入的過程會經過三個Stage : Page_Init => Page_Load => Page_LoadComplete

假如我使用return;(Exit Sub)的話 :
partial class DefaultPage : System.Web.UI.Page
{
protected void Page_Init(object sender, System.EventArgs e)
{
object intNum = "abcde";
int _intNum = 0;
if (!Int32.TryParse(intNum, _intNum)) {
return;
}
System.Diagnostics.Debug.Print("Page_Init is Loaded.");
}

protected void Page_Load(object sender, System.EventArgs e)
{
System.Diagnostics.Debug.Print("Page_Load is Loaded.");
}

protected void Page_LoadComplete(object sender, System.EventArgs e)
{
System.Diagnostics.Debug.Print("Page_LoadComplete is Loaded.");
}
}

Output Window便會顯示出
Page_Load is Loaded.
Page_LoadComplete is Loaded.

換句話說,return並不會中止其後的事件。但如果我們使用throw的話:
partial class DefaultPage : System.Web.UI.Page
{
protected void Page_Init(object sender, System.EventArgs e)
{
object intNum = "abcde";
int _intNum = 0;
if (!Int32.TryParse(intNum, _intNum)) {
throw;
}
System.Diagnostics.Debug.Print("Page_Init is Loaded.");
}

protected void Page_Load(object sender, System.EventArgs e)
{
System.Diagnostics.Debug.Print("Page_Load is Loaded.");
}

protected void Page_LoadComplete(object sender, System.EventArgs e)
{
System.Diagnostics.Debug.Print("Page_LoadComplete is Loaded.");
}
}

這樣Page_Load和Page_LoadComplete都不會執行,而頁面會轉去錯誤信息頁。

當然throw也是一個決定性的做法,正常未必需要因為不符合要求就把瀏覽者轉向錯誤頁面。
但大家從這個範例也可以看出一些ASP.NET Page Cycle上要注意的地方。

1 則留言:

  1. You are MVP now? When? HK MVP? Why not see you on TechDays? Will u go MVP Open Days?

    回覆刪除