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