【关键字】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 |
图2:请求的详细信息 |
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:控件树 |
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:自定义跟踪记录 |
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,之后可以让一些用户使用该应用程序。这样在用户使用过程中,广大程序爱好者可以得到跟踪信息(客户端用户看不到这些信息),从而有利于判断错误的根源。