【摘要】ASP.NET的跟蹤功能比ASP有了很大的提高,通過跟蹤信息有利于判斷WEB應用程序中錯誤的根源。本文通過實例詳細解釋了ASP.NET的跟蹤模式。
【關鍵字】ASP.NET;跟蹤信息;Trace
1、引言
傳統ASP最常用的調試方法是使用Response.Write來設置斷點,在WEB頁面上顯示出某些變量當時的值。但是,這種方法存在不少問題。
(1)在程序中布滿Response.Write語句,這些語句可能反而影響調試,也會影響頁面的布局。
(2)調試結束后,還要痛苦地將這些語句刪掉。而在刪除多余的Response.Write時還要處處小心,防止錯刪必要的Response.Write語句。如果程序有上百行,工作量之大可想而知。
ASP.NET推出了允許直接在代碼中編寫調試語句的新功能,從而在將應用程序部署到生產服務器時,無需將它們從應用程序中移除。該功能叫做跟蹤,允許在頁中編寫變量或結構、斷言是否符合某個條件,或只是通過頁或應用程序的執行路徑進行跟蹤。為了收集并顯示這些消息和其他跟蹤信息,必須啟用頁或應用程序的跟蹤。當啟用跟蹤時,將發生兩件事情:
(1)ASP.NET將一系列診斷信息表緊接著追加在頁輸出之后。還將該信息發送到跟蹤查看器應用程序(只有當已啟用了應用程序的跟蹤時)。
(2)ASP.NET在追加性能數據的Trace Information表中顯示自定義診斷消息。指定的診斷信息和跟蹤消息追加在發送到請求瀏覽器的頁輸出中。或者,可以在單獨的跟蹤查看器(trace.axd)中查看該信息,該查看器顯示給定應用程序中每頁的跟蹤信息。當ASP.NET處理頁請求時,該信息可以幫助查清錯誤或不希望得到的結果。
只有在啟用了跟蹤后才處理并顯示跟蹤語句。可以控制是否將跟蹤顯示到頁上、顯示到跟蹤查看器或既顯示到頁上又顯示到跟蹤查看器。
2、ASP.NET的跟蹤模式的配置
為了能使用跟蹤功能,就要在頁面或整個應用程序的范圍內啟用它。
2.1 頁面級的配置
要在頁面級啟用跟蹤功能,就要在@Page指令中設置Trace屬性。如下所示:
******************************************************************************* <%@ Page Language="vb" Trace="true" Codebehind="WebForm1.aspx.vb" Inherits="WebApplication1.WebForm1"%> ******************************************************************************* |
圖1:跟蹤信息
如果Trace的屬性值為true,那么當頁面被顯示時將在頁面底部顯示跟蹤信息。而使用TraceMode屬性能調整這些信息的顯示順序。TraceMode可選的值有:按照時間順序排列(SortByTime)和按類別(SortCategory),其中,默認值為按照時間順序排列。
2.2 應用程序級的配置
應用程序級的跟蹤功能有多種選擇,可以通過在config.web文件中的<system.web>下增加一個XML元素<trace>來設置。
表1:跟蹤選項
屬性 | 說明 |
Enabled | 如果應用程序中能使用跟蹤功能為true,否則為false |
PageOutput | 如果跟蹤信息顯示在應用程序的頁面上和跟蹤窗口中則為true,否則為false。注意:該屬性將不影響已啟動的跟蹤功能頁 |
RequestLimit | 說明服務器所能存放的跟蹤請求的最大個數。默認為10個 |
TraceMode | 指名按某種順序顯示跟蹤信息。按SortByTime(時間順序)或按用戶定義類型的SortByCategory(字母順序)。默認為按時間順序。 |
LocalOnly | 如果為true,跟蹤窗口(trace.axd)只能顯示在Web服務器的主機上,否則為false。默認為true。 |
******************************************************************************* <configuration> <system.web> <trace Enabled="true" PageOutPut="false" requestLimit="20" traceMode="SortByTime" localOnly="true"/> … </system.web> </configuration> ******************************************************************************* |
雖然例子中使用了所有的屬性,但是并非每個屬性都必須設置。而且頁面級的配置將覆蓋應用程序級的配置。比如,在應用程序級禁用了跟蹤功能,但在頁面級又啟用這個功能,那么跟蹤信息仍會顯示在頁面上。
RequstLimit屬性設置了將被記錄的在跟蹤日志中的請求的個數,這可以避免日志量過大。如果localOnly屬性設為true,那么只在服務器上看到跟蹤信息。這使得只有服務器端可以跟蹤應用程序,而其他用戶卻看不到跟蹤信息。
3、ASP.NET的跟蹤模式的輸出
跟蹤輸出是由TraceContext對象產生的,并分幾部分在ASP.NET頁的底部顯示,如圖1所示。以下是關于這幾個部分和它們的說明。由于跟蹤信息很多,不可能在一個窗口都顯示出來,因此每一類信息由獨立的輸出窗口顯示。
3.1請求的詳細信息
這部分包含了六項信息,如下表所示:
表2:請求信息
信息項 | 說明 |
Session Id | 會話在該服務器上的唯一標識符 |
Time of request | 請求產生的時間 |
Request encoding | 請求的編碼方式,如Unicode |
Request type | Get或Post請求 |
Status | 請求的狀態碼 |
Response Encoding | 響應的編碼方式,如Unicode |
3.2 跟蹤信息
這類信息包含了跟蹤過程中應用程序或ASP.NET引擎輸出的跟蹤信息或警告。默認情況下,ASP.NET引擎將輸出每個實踐開始和結束時的信息,如PreRender、SaveViewState。輸出的信息包括:Category(類別)、Message(消息)、Form First(網頁開始運行算起的時間間隔)以及與Form Last(上一次輸出的跟蹤信息項的時間間隔)。這些信息項的顯示順序由@Page的TraceMode屬性或TraceContext對象的TraceMode屬性值決定的。
跟蹤信息部分非常重要,我將在下一節中詳細闡述。
3.3 控件樹
控件樹信息用樹狀結構顯示了該ASP.NET頁中的所有元素,便于廣大程序員理清控件之間的從屬關系,從而有助于判斷作用域和所有權。每個元素顯示的信息有:控件的Control Id(標識符)、Type(類型)、Render Size Bytes(大小)和ViewState的字節數等。
3.4 Cookies集
Cookies集信息列出了所有與該ASP.NET的web應用程序相關的cookies。顯示的信息包括:Name(名字)、Value(值)和Size(大小)。
3.5 頭消息集
頭消息集包含了所有傳到ASP.NET的網頁中的HTTP的頭消息,每一項都將都將顯示Name(名字)和Value(值)。
3.6 表單消息集
只有當ASP.NET網頁中包含了一個表單,且該表單已被提交到服務器,這類信息才被顯示出來。它包含兩個很重要的信息。
(1) 該網頁的Viewstate,即表單中所有控件的狀態摘要。
(2) 所有控件的Name(名稱)和Value(值)。
4、編寫跟蹤消息
ASP.NET包括Trace對象(與Response、Request或Context對象類似),該對象允許編寫當啟用頁或整個應用程序的跟蹤時出現的調試語句。
ASP.NET使用TraceContext類來存儲有關請求的信息、它的控件層次結構和跟蹤信息。跟蹤信息包括頁請求的某些生命周期階段以及選擇包括的任何自定義語句。通過Page.Trace屬性或Control.Context屬性可以使用TraceContext類。前者在開發ASP.NET頁時可用。后者在要將跟蹤語句包括在自定義服務器控件或要從頁以外(如global.asax文件)包括跟蹤語句時可用。
TraceContext類的接口很簡單,只有一個構造函數、兩個屬性和兩個方法。當然還有一些從Object類繼承下來的屬性和方法。Page對象中的Trace屬性就是一個TraceContext類的實例。TraceContext類提供兩種方法:Write和Warn,這兩種方法允許將語句寫入跟蹤記錄。每種方法都被重載并允許指定跟蹤類別、文本消息和可選錯誤信息。這兩種方法之間的唯一區別就是Warn方法用紅色顯示其文本。
【注意】當在對Write或Warn方法的調用中指定類別時,可以使用該類別對跟蹤語句進行排序。
將重載每種方法,并且每種方法都有三個版本。如果當調用Warn或Write時只包括一個字符串參數,則ASP.NET將此作為消息對待。如果包括兩個參數,將第一個作為類別對待,編程時可以使用該參數對啟用跟蹤時顯示在Trace Information表中的消息進行排序。第三個參數為Exception類型,包含該請求的錯誤信息。
4.1 在頁中將自定義跟蹤消息寫入跟蹤記錄
(1)在頁的代碼聲明塊或代碼隱藏類中,使用Trace屬性調用TraceContext方法之一;
(2)為跟蹤語句指定可選的category參數。可以使用該類別對所顯示的跟蹤語句進行排序;
(3)為跟蹤語句指定message參數。這可以是字符串或方法;
(4)指定可選的errorInfo參數,該參數包含有關頁中任何錯誤的信息;
下面的TraceContext.Warn方法示例定義類別為Render,跟蹤消息為“張志遠在使用Warn跟蹤”。
[C#] Trace.Warn("Render", "張志遠在使用Warn跟蹤。"); [Visual Basic] Trace.Warn("Render", "張志遠在使用Warn跟蹤。") |
下面的屏幕截圖闡釋了當啟用頁的跟蹤時呈現到Trace Information表上的自定義跟蹤語句。Warn方法用于生成第一條以紅色文本顯示的消息,其類別為 Render,消息為“張志遠在使用Warn跟蹤”。Write方法用于生成具有相同類別的第二條自定義消息,但消息為“張志遠在使用Write跟蹤”。
4.2 在自定義服務器控件中將自定義跟蹤消息寫入跟蹤記錄
(1)在服務器控件代碼中,使用Context屬性調用TraceContext方法之一;
(2)為跟蹤語句指定可選的category參數。可以使用該類別對所顯示的跟蹤語句進行排序;
(3)為跟蹤語句指定message參數;
(4)指定可選的errorInfo參數,該參數包含有關頁中任何錯誤的信息;
下面的示例使用Warn方法將自定義語句寫入服務器控件的跟蹤記錄。類別是ZZY Class,消息是“張志遠在跟蹤”。
[C#] Context.Trace.Write("ZZY Class","張志遠在跟蹤。"); [Visual Basic] Context.Trace.Write("ZZY Class","張志遠在跟蹤。") |
4.3 只有在啟用了跟蹤時跟蹤消息寫入記錄
在有些情況下,只有當啟用了跟蹤時,才需要將語句傳遞到Write或Warn方法。TraceContext對象具有布爾屬性(IsEnabled),它允許有條件地調用這些方法。
創建一個If語句,該語句檢查是否為代碼所屬的頁或應用程序啟用了跟蹤,然后創建一個當Trace.IsEnabled屬性返回true時執行的條件語句。
下面的示例確認啟用頁的跟蹤,然后使用Write方法從數據庫中將有關信息寫入Trace Information表。
******************************************************************************* Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load If Trace.IsEnabled Then Trace.Write("Prod", "張志遠在跟蹤") End If End Sub ******************************************************************************* |
5、小結
通過以上的介紹,已經能獲得跟蹤信息了,那么如何利用它們呢?這要根據具體情況而定。大部分跟蹤信息(如cookies、頭信息和服務器變量)在傳統的ASP中也有。只不過它們不像ASP.NET含在跟蹤查看器中。
最能體現ASP.NET的強大的跟蹤功能的是其中的跟蹤信息(這里是指跟蹤輸出的跟蹤信息部分的信息(Message))。有了這部分信息就能了解ASP.NET頁開始運行的時間,以及運行該頁所花的時間。這些信息對于發現應用程序中的性能瓶頸是很重要的。同時,這些信息也有助于解決有些代碼不能正常運行的問題,而這凈化藏是因為代碼沒有按照期望的順序執行,或者是重復執行了。這種錯誤在傳統的ASP中往往很難被發現,而有了這部分的跟蹤信息,這些錯誤就變得顯而易見了。
恰當地使用應用程序級的跟蹤功能,將大大減少調試Web應用程序所花費的時間和精力。如可以在程序中啟用跟蹤功能,并在web.config中將<trace>元素的PageOutPut屬性設置為false,之后可以讓一些用戶使用該應用程序。這樣在用戶使用過程中,廣大程序愛好者可以得到跟蹤信息(客戶端用戶看不到這些信息),從而有利于判斷錯誤的根源。