第 11 章 asp.net 網頁的執行方式. asp.net 的生命週期...
Post on 21-Dec-2015
263 views
TRANSCRIPT
第 11 章 ASP.NET 網頁的執行方式
ASP.NET 的生命週期 讓我們再次回味一下,之前 Web Form 的範例01:<%@ Page Language="VB" %>02:<script runat="server">03: Sub btnOK_Click(ByVal sender As Object, ByVal e As System.EventArgs)04: LBUserName.Text = " 您輸入的姓名為「 " & TBUserName.Text.Trim() & " 」 "05: End Sub06:</script>07:<html>08: <body>09: <form runat="server" id="form1" >10: 姓名: <asp:TextBox runat="server" ID="TBUserName" />11: <asp:Button runat="server" ID="btnOK" Text=" 確定 "
OnClick="btnOK_Click" />12: <asp:Label runat="server" ID="LBUserName" />13: </form>14: </body>15:</html>
ASP.NET 的生命週期 讓我們仔細檢查執行程式後的網頁原始碼。(注意:執行的過程 URL 都一
樣) POSTBACK: 使用者在這個網頁 click 的時候,資料再次回傳給
net1.aspx ,這個動作稱之為 postback 。 <html> <body> <form name="form1" method="post" action="net1.aspx"
id="form1"> <div><input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
value="/wEPDwUKLTczMTE0NTI3OWRkGTrQdmBfrqdGSX6H/DY2ub2kh/0=" /></div>
姓名: <input name="TBUserName" type="text" id="TBUserName" /> <input type="submit" name="btnOK" value=" 確定 " id="btnOK" /> <span id="LBUserName"></span> <div><input type="hidden" name="__EVENTVALIDATION"
id="__EVENTVALIDATION" value="/wEWAwL5irzaCAKVkPWZDALdkpmPAUzvj4J/4rx2uA1thA0iwbRuYasz" /></div>
</form> </body></html>
ASP.NET 網頁的生命週期
設計的動機 每個網頁的執行都是獨立的,完成後就
跟 server 失去連結( disconnected)
造成了所謂的 stateless 解決方案
多網頁的呼叫以及傳遞 單網頁的 POSTBACK ( ASP.NET or
Servlet/JSP )
ASP.NET 網頁的生命週期 生命週期的階段 網頁要求 (page request)
每當使用者要求一個 ASP.NET 網頁 , 一個 Page 的物件就會產生 .
啟動 (start) 初始化 (initialization) 載入 (load) 驗證 (validation) 事件處理 (event handling) 顯示 (rendering) 卸載 (unload)
完成要求之後, Page 物件就被釋放。
保留 Page 的狀態 ASP.NET helps preserve other page
information in the following ways: ASP.NET saves control settings
(properties) between round trips, which is called saving control state.
ASP.NET provides state management capabilities so you can save your own variables and application-specific or session-specific information between round trips.
ASP.NET can detect when a page is requested for the first time and when the page is posted, which allows you to program accordingly.
For instance, you might want to read information from a database the first time a page is displayed, but not on every postback.
1. 初始化階段會依序觸發 Page 物件的PreInit 、 Init 、 InitComplete 事件
2. 載入階段會依序觸發 Page 物件的PreLoad 、 Load 、 LoadComplete 事件
3. 事件處理階段會觸發控制項的事件 ( 如果有指定的話 )
4. 顯示階段會依序觸發 Page 物件的PreRender 、 PreRenderComplete 事件
5. 卸載階段會觸發 Page 物件的 Unload 事件
Page 物件的各個事件都有對應的事件程序,預設的名稱為 Page_event ,例如 Load 事件的事件程序為 Page_Load() ,其形式如下:
Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs)
…End Sub
11-1 Page 類別
single-file 模式
Sysyem.Web.UI.Page類別
Sysyem.Web.UI.Page類別
MyPage.aspx 檔案MyPage.aspx 檔案
ASP.MyPage_aspx 類別ASP.MyPage_aspx 類別
組件 (assembly)組件 (assembly)
產生物件並顯示執行結果產生物件並顯示執行結果
code-behind 模式
Sysyem.Web.UI.Page 類別Sysyem.Web.UI.Page 類別 MyPage.aspx 檔案MyPage.aspx 檔案
MyPage Partial 類別MyPage Partial 類別
組件 (assembly)組件 (assembly)
產生物件並顯示執行結果產生物件並顯示執行結果
MyPage.aspx.vb 檔案MyPage.aspx.vb 檔案
MyPage_aspx 類別MyPage_aspx 類別
11-1-1 Page 類別的屬性
Application Cache ClientTarget="…"
<clientTarget><Add Alias="IE4" UserAgent="Mozilla/4.0 (compatible;
MSIE 4.0; Windows NT 4.0)" /></clientTarget>
ClientScript※ EnableTheming={True|False} ※ EnableViewState={True|False} ErrorPage="URL" 。 Form
IsCrossPagePostBack※ IsPostBack IsValid※ MasterPageFile="…"※ MaxPageStateFieldLength="…"※ PreviousPage※ Request Response Server Session SmartNavigation={True|False} ※ StyleSheetTheme="…"※ Theme="…"※. Trace
11-1-2 Page 類別的方法
Control.DataBind() Control.Dispose() Page.FindControl(id) Control.Focus() ※ Control.HasControls() Page.MapPath(path) TemplateControl.ParseControl(str)
Dim MyText As TextBoxMyText = CType(ParseControl("<asp:TextBox runat=""server"" />"),
TextBox) Control.ResolveUrl(url) Page.SetFocus(control) 、 Page.SetFocus(id) Page.Validate()
Page.ClientScript.RegisterHiddenField(name, value) ※ Page.ClientScript.RegisterClientScriptBlock(type, key,
script)※ Page.ClientScript.RegisterClientScriptInclude(key, url) ※ Page.ClientScript.RegisterStartupScript(type, key, script) ※ Page.ClientScript.RegisterOnSubmitStatement(type, key,
script) ※ Page.ClientScript.IsClientScriptBlockRegistered(key) ※ Page.ClientScript.IsClientScriptIncludeRegistered(key) ※ Page.ClientScript.IsStartupScriptRegistered(key) ※ Page.ClientScript.IsOnSubmitStatementRegistered(key)
\Ch11\MapPath.aspx<%@ Page Language="VB" %><script runat="server"> Sub Page_Load(ByVal sender as Object, ByVal e as
System.EventArgs) Response.Write(" 父目錄為 " & Page.MapPath("../") & "<br>") Response.Write(" 目前目錄為 " & Page.MapPath("./") &
"<br>") Response.Write(" 根目錄為 " & Page.MapPath("/") & "<br>") Response.Write(" 網頁實際路徑為 " &
Page.MapPath("MapPath.aspx")) End Sub</script>
11-1-3 Page 類別的事件 AbortTransaction CommitTransaction DataBinding Disposed Error SaveStateComplete※ PreInit※ Init : InitComplete※ PreLoad※ Load LoadComplete※ PreRender PreRenderComplete※ Unload
\Ch11\Page_Init.aspx01:<%@ Page Language="VB" %>02:<script runat="server">03: Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs)04: SelectList.Items.Add(" 二二八公園 ")05: SelectList.Items.Add(" 外雙溪 ")06: SelectList.Items.Add(" 青年公園 ")07: End Sub08:09: Sub AddDest(ByVal sender As Object, ByVal e As System.EventArgs)10: SelectList.Items.Add(Destination.Text)11: End Sub12:</script>13:<html>14: <body>15: <form runat="server">16: 旅遊地點: <asp:DropDownList runat="server" ID="SelectList" />17: <br><br> 增加旅遊地點:18: <asp:TextBox runat="server" ID="Destination" />19: <asp:Button runat="server" Text=" 新增 " OnClick="AddDest" />20: </form>21: </body>22:</html>
11-3 PostBack
下面是一個例子:
\Ch11\PostBack.aspx01:<%@ Page Language="VB" %>02:<script runat="server">03: Sub Page_Load(ByVal sender as Object, ByVal e as
System.EventArgs)04: If Not Page.IsPostBack Then05: InputPanel.Visible = True06: ResultPanel.Visible = False07: Else08: InputPanel.Visible = False09: ResultPanel.Visible = True10: End If11: End Sub12:13: Sub Button_Click(ByVal sender as Object, ByVal e as
System.EventArgs)14: ShowCash.Text = Cash.Text15: ShowRate.Text = Rate.Text16: ShowTotal.Text = Cash.Text + Cash.Text * Rate.Text17: End Sub18:</script>
19:<html> 20: <body> 21: <form runat="server" method="post"> 22: <asp:Panel runat="server" ID="InputPanel"> 23: 請輸入本金 ( 例如 500000) : <asp:TextBox runat="server"
ID="Cash" /><br> 24: 請輸入年利率 ( 例如 0.05) : <asp:TextBox runat="server" ID="Rate"
/><br> 25: <asp:Button runat="server" Text=" 開始計算 "
OnClick="Button_Click" /> 26: </asp:Panel> 27: <asp:Panel runat="server" ID="ResultPanel"> 28: 當本金為 <asp:Label runat="server" ID="ShowCash" /> 、 29: 年利率為 <asp:Label runat="server" ID="ShowRate" /> 時, 30: 一年的本利和為 <asp:Label runat="server" ID="ShowTotal" /> 。 31: </asp:Panel> 32: </form> 33: </body> 34:<html>
11-4 將網頁導向到其它網頁
11-4-1 Cross-Page Posting 下面是一個例子:
\Ch11\Cross1.aspx01:<html>02: <body>03: <form runat="server" method="post">04: 請輸入本金 ( 例如 500000) : <asp:TextBox runat="server" ID="Cash"
/><br>05: 請輸入年利率 ( 例如 0.05) : <asp:TextBox runat="server"
ID="Rate" /><br>06: <asp:Button runat="server" Text=" 開始計算 "
PostBackUrl="Cross2.aspx" />07: </form>08: </body>09:<html>
\Ch11\Cross2.aspx01:<%@ Page Language="VB" %>02:<script runat="server">03: Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs)04: Dim TB1 As TextBox = CType(PreviousPage.FindControl("Cash"),
TextBox)05: Dim TB2 As TextBox = CType(PreviousPage.FindControl("Rate"),
TextBox)06: ShowCash.Text = TB1.Text07: ShowRate.Text = TB2.Text08: ShowTotal.Text = TB1.Text + TB1.Text * TB2.Text09: End Sub10:</script>11:<html>12: <body>13: <form runat="server" method="post">14: 當本金為 <asp:Label runat="server" ID="ShowCash" /> 、15: 年利率為 <asp:Label runat="server" ID="ShowRate" /> 時,16: 一年的本利和為 <asp:Label runat="server" ID="ShowTotal" /> 。17: </form>18: </body>19:<html>
課本 11-25 頁的 if 錯誤If Page.IsCrossPagePostBack then …Else Response.Redirect(“Cross1.aspx”)End if 不能使用 Page.IsCrossPagePostBack 要使用 Page.PreviousPage.IsValid 且 / 或
PreviousPage. IsCrossPagePostBack 主要的目的在於檢查使用者不是直接執行
Cross2.aspx 這個網頁。
11-4-2 呼叫 Response.Redirect() 方法導向到其它網頁
使用 HTML 語法的 <meta> 標籤,可以寫成如下:
<meta http-equiv=refresh content="2; url=http://tw.yahoo.com">
或者可以呼叫 Response.Redirect() 方法,其語法如下: Redirect(url) Redirect(url, endResponse)
endResponse 是 boolean 值,代表目前的這個網頁是否結束。若只呼叫 Redirect(url) ,預設行為是 true 。
11-4-2 Redirect 下面是一個例子 : \Ch11\Page1.aspx
<%@ Page Language="VB" %><script runat="server"> Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs) Dim WeekDay As Integer Dim PageName As String WeekDay = DateTime.Today.DayOfWeek() ' 取得今天是星期幾 Select Case WeekDay ' 根據星期幾決定要顯示的網頁名稱 Case "0" PageName = "Sun.htm" Case "1" PageName = "Mon.htm" Case "2" PageName = "Tue.htm" Case "3" PageName = "Wed.htm" Case "4" PageName = "Thu.htm" Case "5" PageName = "Fri.htm" Case "6" PageName = "Sat.htm" End Select Response.Redirect(PageName) End Sub</script>
11-4-3 呼叫 Server.Transfer() 方法轉移到其它網頁
下面是一個例子 :\Ch11\Page1.aspx<%@ Page Language="VB" %><script runat="server"> Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs) Context.Items.Add("Message", " 在 Page1 的設定值 ") Response.Write("<p> 呼叫 Transfer() 方法之前 </p>") Server.Transfer("Page2.aspx") Response.Write("<p> 呼叫 Transfer() 方法之後 </p>") End Sub</script>
\Ch11\Page2.aspx<%@ Page Language="VB" %><script runat="server"> Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs) Response.Write("<p> 這是 Page2.aspx 的執行結果 </p>") Response.Write(Context.Items("Message")) End Sub</script>
11-4-3 Server.Transfer vs. Response.Redirect
Response.Redirect 瀏覽器知道這項改變 轉移的時候不會保留內建物件的值
Server.Transfer 瀏覽器不知道這項改變 轉移的時候會保留內建物件的值: Context
、 Request 、 Session 、 Application 等 Context 是屬於 HttpContext 型態,也是
Page 物件的一個屬性 練習題:試著改變 Page1.aspx 使得使
用者傳入姓名,但是卻在 Page2.aspx 中顯示(或者處理)
11-4-4 使用超連結導向到其它網頁
如果純粹要讓使用者瀏覽其它網頁,沒有要進行額外的處理,可以透過HTML 語法的 <a>…</a> 標籤或HyperLink 控制項建立超連結。
11-5 傳送用戶端指令碼給瀏覽器
Page.ClientScript.RegisterClientScriptBlock(type, key, script) ※
Page.ClientScript.RegisterClientScriptInclude(key, url) ※ Page.ClientScript.RegisterStartupScript(type, key, script)
※ Page.ClientScript.RegisterOnSubmitStatement(type, key,
script) ※ Page.ClientScript.IsClientScriptBlockRegistered(key) ※ Page.ClientScript.IsClientScriptIncludeRegistered(key) ※ Page.ClientScript.IsStartupScriptRegistered(key) ※
下面是一個例子 :
\Ch11\RegisterClientScriptBlock.aspx01:<%@ Page Language="VB" %>02:<script runat="server">03: Sub Page_Load(ByVal sender as Object, ByVal e as System.EventArgs)04: Dim Script As String05: Script = "<Script Language='JavaScript'> function DoClick() {"06: Script += "myForm.Message.value=' 成功地傳送用戶端指令碼 '}<"07: Script += "/Script>"08:09: If Not Page.ClientScript.IsClientScriptBlockRegistered("clientScript")
Then10: Page.ClientScript.RegisterClientScriptBlock(Me.GetType(),
"clientScript", Script)11: End If12: End Sub13:</script>14:<html>15: <body>16: <form id="myForm" runat="server">17: <input type="Button" value=" 傳送 " onclick="DoClick()"><br>18: <input type="Text" id="Message">19: </form>20: </body>21:</html>
11-6 CallBack
PostBack
使用者提交表單並PostBack 回原網頁
初始化初始化
載入狀態載入狀態
處理 PostBack 資料處理 PostBack 資料
載入載入
PostBack 事件PostBack 事件
儲存狀態儲存狀態
顯示顯示
卸載卸載
CallBack
使用者提交表單並CallBack 回原網頁
初始化初始化
傳回 CallBack結果
載入狀態載入狀態
處理 PostBack 資料處理 PostBack 資料
載入載入
CallBack 事件CallBack 事件
卸載卸載
JavaScript 事件程序JavaScript 事件程序向伺服器提出非同步要求
撰寫具有 CallBack功能的 ASP.NET 網頁必須執行下列動作:
實作 ICallbackEventHandler介面Partial Class ClientCallback Inherits System.Web.UI.Page Implements System.Web.UI.ICallbackEventHandler
<%@ Page Language="VB" %><%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %>
實作 RaiseCallbackEvent() 和 GetCallbackResult() 方法Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _
Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
cbResult = CInt(Rnd() * 10).ToString()End Sub
Public Function GetCallbackResult() As String _ Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
Return cbResult End Function
此外,還要包含用戶端指令碼函式以執行下列動作:
傳送 CallBack 給伺服器Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
Me.Load Dim cbReference As String = Page.ClientScript.GetCallbackEventReference(Me, _
"arg", "GetNumberFromServer", "context") Dim cbScript As String = "function CallServer(arg, context) { " & cbReference &
"};" Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", cbScript,
True)End Sub
接收 Callback<script type="text/javascript"> function GetNumber(){ CallServer(); } function GetNumberFromServer(TextBox1, context){ document.form1.TextBox1.value = TextBox1; }</script>
Partial Class ClientCallback Inherits System.Web.UI.Page Implements System.Web.UI.ICallbackEventHandler
Dim cbResult As String Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim cbReference As String = Page.ClientScript.GetCallbackEventReference(Me, _ "arg", "GetNumberFromServer", "context") Dim cbScript As String = "function CallServer(arg, context) { " & _ cbReference & "};" Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), _ "CallServer", cbScript, True) End Sub
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) _ Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent cbResult = CInt(Rnd() * 10).ToString() End Sub
Public Function GetCallbackResult() As String _ Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult Return cbResult End FunctionEnd Class
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="ClientCallback.aspx.vb" Inherits="ClientCallback" %>
<html> <head runat="server"> <script type="text/javascript"> function GetNumber(){ CallServer(); } function GetNumberFromServer(TextBox1, context){ document.form1.TextBox1.value = TextBox1; } </script> </head> <body> <form runat="server" id="form1"> <button onclick="GetNumber()">取得亂數</button><br> <asp:TextBox runat="server" ID="TextBox1" /> </form> </body></html>
<%@ Page Language="VB" %><%@ Implements Interface="System.Web.UI.ICallbackEventHandler" %><script runat="server"> Dim cbResult As String
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent cbResult = CInt(Rnd() * 10).ToString() End Sub
Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult Return cbResult End Function
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load Dim cbReference As String = Page.ClientScript.GetCallbackEventReference(Me, "arg", "GetNumberFromServer", "context") Dim cbScript As String = "function CallServer(arg, context) { " & cbReference & "};" Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "CallServer", cbScript, True) End Sub</script>
<html> <head runat="server"> <script type="text/javascript"> function GetNumber(){ CallServer(); } function GetNumberFromServer(TextBox1, context){ document.form1.TextBox1.value = TextBox1; } </script> </head> <body> <form runat="server" id="form1"> <button onclick="GetNumber()">取得亂數 </button><br> <asp:TextBox runat="server" ID="TextBox1" /> </form> </body></html>
CallBack
概念上,與 Web 2.0 (或者 AJAX)相同網頁並沒有更新,只有所需要的資料更
新目前,無法與 FireFox 合用,只能
用於 IE練習題:請利用亂數的值來決定選擇某一本書,並將書名列印出來
練習題:由使用者決定選擇某一本書,並將書名列印出來