逐步解說:使用 Visual Web Developer 中的追蹤功能協助找出 Web 網頁錯誤
更新:2007 年 11 月
有數個方法可以找出 ASP.NET Web 網頁中的錯誤。這包括使用偵錯工具和追蹤。追蹤會顯示在網頁處理期間發生之動作的訊息,也可以包括您選擇顯示的資訊。追蹤還會提供伺服器和瀏覽器所交換之資料的相關資訊。資料交換包括控制項詳細資料、伺服器變數、使用者名稱、Cookie 等。這個逐步解說說明如何使用追蹤。
追蹤在使用偵錯工具不實用或不太好時很有用。例如,偵錯工具可能因為網頁位於遠端伺服器上而不可用。追蹤還可讓您輕鬆檢視在偵錯工具中不是明確可用的資訊 (例如,HTTP 標頭)。如需偵錯的詳細資訊,請參閱逐步解說:在 Visual Web Developer 中進行 Web 網頁偵錯。
在這個逐步解說中,您將使用追蹤。您將建立一個 Web 網頁,提示使用者輸入名稱,然後顯示該名稱。網頁還會將名稱儲存在 Cookie 中,以便使用者無需重新輸入名稱。
注意事項: |
---|
在實際執行應用程式中,儲存個人資訊更好的技術是使用 ASP.NET 設定檔屬性。如需詳細資訊,請參閱 ASP.NET 設定檔屬性概觀。然而,使用這個逐步解說中的 Cookie 會簡化程式碼,讓您專注於追蹤。 |
在這個逐步解說中,您將故意引入一些錯誤。然後,將使用追蹤以查看網頁處理的狀態,這將有助於診斷錯誤。
本逐步解說將說明的工作包括下列項目:
啟用單一網頁的追蹤。
讀取追蹤輸出。
顯示自訂追蹤資訊。
在另一個追蹤視窗檢視追蹤資訊。
建立自訂追蹤輸出。
必要條件
若要完成這個逐步解說,您必須進行下列步驟:
Microsoft Visual Web Developer Web 開發工具。
.NET Framework。
本逐步解說假設您已對 Visual Web Developer 中的工作具有一般了解。如需 Visual Web Developer 的簡介,請參閱逐步解說:在 Visual Web Developer 中建立基本 Web 網頁。
建立網站
如果您已經藉由完成逐步解說:在 Visual Web Developer 中建立基本 Web 網頁中的步驟而在 Visual Web Developer 中建立了網站,則可使用該網站,並繼續進行這個逐步解說中稍後之「加入控制項」的步驟。否則,依照下列這些步驟建立新的網站和 Web 網頁。
注意事項: |
---|
這個逐步解說假設您使用之 ASP.NET Web 網頁的程式碼使用程式碼後置 (Code-Behind) 的檔案。 |
若要建立檔案系統網站
開啟 Visual Web Developer。
在 [檔案] 功能表上,按一下 [新網站]。
[新網站] 對話方塊隨即出現。
請在 [Visual Studio 安裝的範本] 下方,按一下 [ASP.NET 網站]。
在最右邊的 [位置] 方塊中,輸入您想要用來保存網站頁面的資料夾名稱。
例如,輸入資料夾名稱 C:\WebSites。
在 [語言] 清單中,按一下您想要操作的程式語言。
按一下 [確定]。
Visual Web Developer 會建立資料夾和命名為 Default.aspx 的新頁面。
加入網頁
如果您是在使用現有網站,則可以建立新的網頁。如果您具有可用於這個逐步解說的網頁,請繼續進行下一節的步驟。
若要建立新網頁
在 [方案總管] 中,以滑鼠右鍵按一下網站名稱,然後按一下 [加入新項目]。
在 [加入新項目 <Path>] 對話方塊中的 [Visual Studio 安裝的範本] 下,按一下 [Web Form]。
在 [名稱] 方塊中,輸入 FirstWebPage.aspx。
在 [語言] 清單中,按一下您想要操作的程式語言。
如果以 Visual Basic 或 C# 建立網頁,則選取 [將程式碼置於個別檔案中] 核取方塊。
按一下 [加入]。
加入控制項
建立網站並開啟網頁後,下一步是將部分控制項加入網頁。
若要加入用於偵錯的控制項和程式碼
切換至 [設計] 檢視,然後從 [工具箱] 的 [標準] 群組,將下列控制項拖曳至網頁,並依照表格中的指示設定其屬性。
控制項
屬性
TextBox
ID:textName
Text:(空白)
Button
ID:buttonDisplayName
Text:送出
Label
ID:labelName
Text:(空白)
注意事項: 在此逐步解說中,頁面的配置並不重要。
加入程式碼
下一步是將程式碼加入網頁。網頁正確執行時,使用者可以輸入名稱,然後按一下 [送出],會將名稱顯示在 Label 控制項中。如果使用者關閉瀏覽器,然後再返回網頁,則網頁將已經具有使用者的名稱,因為其儲存在 Cookie 中。
下列步驟會引導您加入程式碼。此處加入程式碼的程序或程式碼自身都不完全正確。這是故意的,以便可以使用追蹤找出網頁上的錯誤。
若要加入程式碼
在 [方案總管] 中,以滑鼠右鍵按一下 [FirstWebPage.aspx],再按 [檢視程式碼]。
注意事項: 不要按兩下 [設計] 檢視中的按鈕。
在類別 (Class) 定義中,輸入下列程式碼。
注意事項: 如果您是在使用單一檔案網頁,請將程式碼貼至 <script> 區塊中。
Protected Sub buttonDisplayName_Click(ByVal sender As Object, _ ByVal e As EventArgs) labelName.Text = Server.HtmlEncode(textName.Text) Response.Cookies("username").Value = labelName.Text End Sub
protected void buttonDisplayName_Click(Object sender, EventArgs e) { labelName.Text = Server.HtmlEncode(textName.Text); Response.Cookies["username"].Value = labelName.Text; }
程式碼會執行下列工作:
其會讀取 TextBox 控制項的值,然後將值顯示在 Label 控制項中。做為這個邏輯的一部分,程式碼會呼叫 HtmlEncode 方法,該方法可能會將可執行的 HTML 字元 (例如,右角括弧 (<)) 轉換成其對等的顯示字元。這是防範擅用指令碼的安全措施。如需詳細資訊,請參閱指令碼攻擊。
它會建立名為 username 的 Cookie,該 Cookie 會儲存使用者輸入的值。
將下列方法加入您在之前步驟建立之 Click 處理常式的上方或下方。
Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.Load If Not Request.Cookies("username") Is Nothing Then labelName.Text = Request.Cookies("username").Value End If End Sub
void Page_Load(Object sender, EventArgs e) { if(Request.Cookies["username"] != null) { labelName.Text = Request.Cookies["username"].Value; } }
測試網頁
您現在可以測試網頁。如果您遵循前一節中程序之故意不完整的步驟,則網頁仍將無法依設計運作。
若要測試網頁
按 CTRL+F5 執行頁面。
網頁出現後,在文字方塊中輸入名稱,然後按一下 [送出]。
請注意,即使按一下 [送出] 會讓網頁回傳至伺服器,但是您的名稱仍未顯示。
關閉瀏覽器。
您現在可以使用追蹤以協助您找出網頁中的錯誤。
使用追蹤找出錯誤
在本節中,您將啟用網頁的追蹤。您將檢查追蹤輸出,然後加入將協助您找出網頁錯誤的自訂追蹤訊息。
若要啟用網頁的追蹤
開啟 FirstWebPage.aspx 網頁,並切換至 [設計] 檢視。
在清單的 [屬性] 中,按一下 [DOCUMENT]。
這將顯示網頁的屬性。
將 [追蹤] 設為 true。
追蹤設定實際上是做為 @ Page 指示詞的一部分。您可以藉由切換至 [來源] 檢視並查看網頁中的第一行,以查看該設定。@ Page 指示詞看起來與下列內容類似:
<%@ Page language="VB" Trace="true" %>
<%@ Page language="C#" Trace="true" %>
按 CTRL+F5 執行網頁。
此網頁便會顯示在瀏覽器中。在頂部,您會看到放置在網頁上的文字和控制項。在文字和控制項之下,您會看到追蹤輸出,其顯示許多網頁處理的詳細資料,還包含下列資訊:
網頁執行期間發生之網頁事件的序列 (Sequence)。
網頁上控制項的型別、名稱和大小。
Cookie 和其內容。
伺服器變數,其為瀏覽器傳送至伺服器的所有資訊集合。
請注意,在 [要求的詳細資訊] (追蹤資訊的第一個區塊) 下,[要求類型] 為 [GET]。這表示這是第一次執行網頁,也就是說,不是回傳。
在方塊中,輸入名稱,然後按一下 [送出]。
[要求類型 現在是 [POST]。這表示這是網頁的回傳。按一下 [送出] 不會顯示名稱。
關閉瀏覽器。
您可以使用自訂追蹤輸出以協助您遵循網頁的邏輯。
若要加入自訂追蹤輸出
將下列粗體顯示的行加入這個逐步解說中之前之「加入程式碼」中建立的 buttonDisplayName_Click 處理常式:
Protected Sub buttonDisplayName_Click(ByVal sender As Object, _ ByVal e As EventArgs) Trace.Warn("debugging", "Start buttonDisplayName Click handler") labelName.Text = Server.HtmlEncode(textName.Text) Response.Cookies("username").Value = labelName.Text Trace.Warn("debugging", "End buttonDisplayName Click handler") End Sub
protected void buttonDisplayName_Click(Object sender, EventArgs e) { Trace.Warn("debugging", "Start buttonDisplayName Click handler"); labelName.Text = Server.HtmlEncode(textName.Text); Response.Cookies["username"].Value = labelName.Text; Trace.Warn("debugging", "End buttonDisplayName Click handler"); }
Warn 方法將自訂訊息加入追蹤輸出。儘管 TraceContext 類別也提供 Write 方法,但是 Warn 方法更有用,因為輸出是以彩色顯示。
按 CTRL+F5 執行頁面。
按一下 [送出]。
當檢查追蹤輸出時,您將注意到輸出不包含紅色文字。由此您可以得出結論:未呼叫 [送出] 的 Click 處理常式。
未呼叫處理常式最常見的原因是控制項未正確繫結至事件處理常式。這種情況就是這樣:儘管加入了事件處理程式碼,但是您未將 [送出] 的 Click 事件繫結至處理常式。通常,Visual Web Developer 會在您按兩下 [設計] 檢視中的控制項後,將事件繫結至控制項。
關閉瀏覽器。
在 [來源] 檢視中,將下列粗體顯示的屬性 (Attribute) 加入 <asp:button> 項目:
<asp:button id="buttonDisplayName" text="Submit" onclick="buttonDisplayName_Click" />
按 CTRL+F5 執行頁面。
在方塊中,輸入名稱,然後按一下 [送出]。
您的自訂追蹤輸出會在 [追蹤資訊] 區段中顯示為紅色,列出網頁進行的處理步驟。
該區段中的輸出以網頁處理期間訊息發生的順序顯示訊息。將訊息加入 Click 事件處理常式中,然後該處理常式在 Begin Raise PostBackEvent 和 End Raise PostBackEvent 行之間進行處理。加入自訂訊息不僅可讓您了解是否呼叫了處理常式,而且還可讓您了解在網頁處理循環中程式碼執行的位置。
自訂訊息旁邊的分類為 debugging,它是您在呼叫 Warn 方法時指定的分類。您可以指定任何想要的分類,如果有用,您可以將網頁的 TraceMode 屬性設為 SortByCategory 值,以輕鬆找出追蹤輸出中的分類。
另外,請注意您輸入的名稱顯示在標籤 (Label) 中。
既然 [送出] 的 Click 處理程式正確運行,您就可以測試網頁中的其餘程式碼,包括 Cookie。
若要測試 Cookie
關閉瀏覽器。
按 CTRL+F5 執行頁面。
預期的行為是您輸入的名稱會自動顯示在標籤中,因為 [送出] 的 Click 處理常式會設定 Cookie,且 Page_Load 處理常式會在下一個回傳期間讀取它。然而,標籤決不會從 Cookie 設定。
如果正在撰寫 Cookie,但未保存,則錯誤經常是未設定明確的 Cookie 到期日。沒有到期日的 Cookie 是工作階段 (Session) Cookie。工作階段 Cookie 只有在瀏覽器關閉之後才可以保留在伺服器記憶體中。換言之,Cookie 未寫入瀏覽器。在下列步驟中,您將更正這個問題。
關閉瀏覽器。
在 [來源] 檢視中,將下列粗體顯示行加入 buttonDisplayName_Click 處理常式:
Protected Sub buttonDisplayName_Click(ByVal sender As Object, _ ByVal e As EventArgs) Trace.Warn("debugging", "Start buttonDisplayName Click handler") labelName.Text = Server.HtmlEncode(textName.Text) Response.Cookies("username").Value = labelName.Text Response.Cookies("username").Expires= _ DateTime.Now.AddMinutes(30) Trace.Warn("debugging", "End buttonDisplayName Click handler") End Sub
protected void buttonDisplayName_Click(Object sender, EventArgs e) { Trace.Warn("debugging", "Start buttonDisplayName Click handler"); labelName.Text = Server.HtmlEncode(textName.Text); Response.Cookies["username"].Value = labelName.Text; Response.Cookies["username"].Expires= DateTime.Now.AddMinutes(30); Trace.Warn("debugging", "End buttonDisplayName Click handler"); }
新行明確地將 Cookie 設為在 30 分鐘後到期。
按 CTRL+F5 執行頁面。
在方塊中,輸入名稱,然後按一下 [送出]。
名稱便會顯示在瀏覽器中。在 [回應 Cookie 集合] 追蹤輸出中,您可以看到正在設定 Cookie。
關閉瀏覽器。
按 CTRL+F5 執行頁面。
此時,會自動將名稱填入。在 [要求 Cookie 集合] 追蹤輸出中,現在您可以看到瀏覽器正在將 Cookie 傳遞至網頁。
在追蹤檢視器視窗中顯示追蹤資訊
當您只使用第一網頁時,設定網頁顯示追蹤輸出將非常有用。然而,如果您是在應用程式中使用許多網頁,則為每個網頁設定啟用和停用追蹤不太方便。而且,網頁正在執行時,在網頁中顯示追蹤輸出資訊可能會覺得很混亂。無論如何,您不希望網頁對應用程式的使用者顯示追蹤輸出。
您不僅可以在網頁層級設定追蹤,也可以在應用程式層級設定追蹤。設定應用程式層級追蹤具有兩個優點:
您可以同時啟用和停用所有網頁的追蹤。
您可以在另一個瀏覽器視窗 (追蹤檢視器) 顯示追蹤輸出,而不是將其做為網頁之輸出的一部分顯示。
當應用程式層級追蹤啟用時,ASP.NET 會將所有網頁的追蹤輸出保留在快取中。您可以設定選項,以指定快取追蹤輸出網頁的數量,以及是要保留最新的項目還是最舊的項目。然後您可以在瀏覽器中叫用 (Invoke) 追蹤檢視器,並選取要檢查的追蹤輸出。
在本節的逐步解說中,您將啟用應用程式層級追蹤,並使用追蹤檢視器檢查追蹤輸出。
若要啟用應用程式層級追蹤
切換至 [來源] 檢視,然後在網頁頂部的 @ Page 指示詞中,刪除 Trace="true"。
注意事項: 移除屬性,不要只是將其設為 false。否則,這個逐步解說中的後續步驟將無法正常運作。
在 [網站] 功能表上,按一下 [ASP.NET 組態]。
便會出現 ASP.NET 網站管理工具。
按一下 [應用程式組態]。
在 [偵錯及追蹤] 下,按一下 [設定偵錯及追蹤],然後選取 [擷取追蹤資訊] 核取方塊。
這個設定會啟用應用程式層級追蹤。
在此逐步解說中,您可以保留剩餘設定的預設值。ASP.NET 將快取最多 10 個項目的追蹤輸出,(單一網頁的10 個回傳,或多個網頁中每個網頁的較少回傳),並快取最新的項目。
關閉 ASP.NET 網站管理工具。
現在您可以執行原始網頁,並以使用者可以看到的方式使用。然而,同時您必須可以在另一個瀏覽器視窗中檢視追蹤輸出。
若要在另一個瀏覽器視窗中檢視追蹤輸出
按 CTRL+F5 執行頁面。
請注意,網頁不再顯示追蹤輸出。網頁會以使用者看到的方式顯示。
在方塊中,輸入名稱,然後按一下 [送出] 以確認網頁正確運作。
開啟新的瀏覽器視窗。
在瀏覽器的 [位址] 方塊中,輸入網站的 URL,用 trace.axd 代替您正在使用的網頁名稱。
例如,如果網頁的 URL 如下:
https://localhost:8081/WebSite/Default.aspx
輸入下列命令:
https://localhost:8081/WebSite/trace.axd
注意事項: 執行這項工作的快速方式是從原始網頁複製 URL,然後只變更網頁名稱。
瀏覽器會顯示追蹤項目的目前快取。
按一下前一個 (最新) 追蹤項目的 [檢視詳細資料]。
瀏覽器顯示的追蹤輸出與您在之前之逐步解說中看到的類似,只是它未附加至網頁的結尾。
切換至包含原始網頁的瀏覽器執行個體。
在方塊中,輸入新的名稱,然後按一下 [送出]。
這個動作會產生新的追蹤記錄項目。
切換至包含資訊的瀏覽器執行個體。
在瀏覽器中,按一下 [上一步] 以返回清單追蹤項目,再按 [重新整理] 以更新項目的清單。
會出現新的項目,表示您在步驟 7 中建立的追蹤輸出。
關閉這兩個瀏覽器視窗。
建立自訂追蹤輸出
如您所看到的,追蹤輸出包含許多資訊,有時多於您的需要。例如,您可能想要將追蹤輸出限制為只有您自己建立的追蹤輸出。追蹤可讓您讀取追蹤緩衝區的內容,並有選擇地顯示您需要的資訊。
若要建立自訂追蹤輸出,請處理 Trace 物件的 TraceFinished 事件。在事件處理常式中,您可以讀取追蹤緩衝區。
若要建立自訂追蹤輸出
在您使用過的網頁中,將下列粗體顯示的程式碼加入至 Page_Load 處理常式:
Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles Me.Load If Not Request.Cookies("username") Is Nothing Then labelName.Text = Request.Cookies("username").Value End If AddHandler Trace.TraceFinished, AddressOf Me.TraceFinished If IsPostBack Then Trace.Write("debugging", "Page_Load (Postback)") Else Trace.Write("debugging", "Page_Load (First Time)") End If End Sub
void Page_Load(object sender, EventArgs e) { if(Request.Cookies["username"].Value != null) { labelName.Text = Request.Cookies["username"].Value; } Trace.TraceFinished += new TraceContextEventHandler(this.TraceFinished); if (Page.IsPostBack) { Trace.Write("debugging", "Page load (postback)"); } else { Trace.Write("debugging", "Page load (first time)"); } }
程式碼會執行下列兩個功能:
它將網頁中的方法繫結至 Trace 物件的 TraceFinished 事件,它將在網頁的追蹤輸出完成後引發。您將在下個步驟寫入方法。
它會撰寫部分追蹤資訊。
建立下列方法,以處理 TraceFinished 事件:
Sub TraceFinished(ByVal sender As Object, _ ByVal e As TraceContextEventArgs) Dim traceRecord As TraceContextRecord For Each traceRecord In e.TraceRecords If traceRecord.Category = "debugging" Then Response.Write("<BR>" & traceRecord.Message) End If Next End Sub
void TraceFinished(object sender, TraceContextEventArgs e) { foreach(TraceContextRecord traceRecord in e.TraceRecords) { if(traceRecord.Category == "debugging") { Response.Write("<br>" + traceRecord.Message); } } }
這個程式碼在追蹤輸出完成後執行。追蹤緩衝區可用做 e 事件引數之 TraceRecords 屬性中的集合。程式碼會在集合中執行迴圈 (Loop),並顯示任何以 debugging 做為其分類之追蹤記錄的值。在這個逐步解說中,您將所有自訂追蹤輸出的分類設為 debugging。
此時在逐步解說中,網站設定為啟用所有網頁的追蹤,但會將追蹤輸出導向至追蹤檢視器,而不是導向至網頁。如果網站的設定不同 (例如,如果追蹤輸出顯示在網頁中),請遵循逐步解說之前之「在追蹤檢視器視窗顯示追蹤資訊」中名為「若要啟用應用程式層級追蹤」程序中的步驟。
您現在可以測試自訂追蹤輸出。
若要測試自訂追蹤輸出
按 CTRL+F5 執行頁面。
當網頁顯示在瀏覽器中時,訊息 [頁面載入 (第一次)] 隨即出現,但不會出現其他追蹤輸出。
按一下 [送出]。
訊息 [頁面載入 (回傳)]、[Start buttonDisplayName Click 處理常式] 和 [End buttonDisplayName Click 處理常式 隨即出現。
注意事項: |
---|
如果您超過在 trace 項目 (ASP.NET 設定結構描述) 之 requestLimit 屬性中指定的快取要求數目,則將不會引發 TraceFinished 事件,您將看不到 Web 網頁上的訊息。 |
後續步驟
這個逐步解說說明了 ASP.NET 中追蹤的基本功能。除了使用追蹤在 Web 應用程式內顯示資訊之外,您還可以將 ASP.NET 追蹤與其他檢測整合。例如,您可能會想要進行下列動作:
將系統診斷訊息做為 ASP.NET 追蹤的一部分顯示。
如需詳細資訊,請參閱逐步解說:將 ASP.NET 追蹤與 System.Diagnostics 追蹤整合。
將 ASP.NET 追蹤資訊傳送至 .NET Framework 追蹤機制,其使用 System.Diagnostics 命名空間中的類別。
將資訊做為網站健康監視的一部分轉寄至已註冊的檢測接聽程式。
如需註冊接聽程式的詳細資訊,請參閱 <trace> 的 <listeners> 項目。