ASPNET具有一个很好的新功能它对运行时间错误的处理和跟蹤提供了丰富支持特别是它为管理人员提供了一种很简单的方法可以保证那些令人恐惧的ASP ax十六进制形式的错误永远也不会被显示到客户面前相反它允许显示一个较为定制化的信息比如对不起这个站点不可用ASPNET还提供了一种强大的方法使开发人员可以对他们的代码进行装备向管理人员提供发生在工作站点问题的额外信息与通知本文详细介绍了这两种技术同时在结尾包括了一个样本代码你可以直接使用它试验一下
确保不会洩露安全信息
ASPNET同以前的ASP一样当服务器上发生了一个运行时间或编译时间错误时就会生成一个html 错误页面但是与ASP不同ASPNET格外关注的是要确保在默认状态下不会因为这个错误的发生而洩露安全信息尤其是如果你从一个远程机器上点击服务器的话out of the box型的错误处理设置将不会导致显示远程机器的编译器信息洩露配置信息文件名堆栈记录 源代码或线性数据相反远程用户只会看到一个如发生了应用程序错误的普通信息要想查看错误细节用户必须要)从本地服务器再次点击页面或者是 )在机器或应用程序的configweb文件中修改配置的设置来允许远程访问
<configuration>
<customerrors mode=off />
</configuration>
我们希望通过将默认状态设置成我们不得不安全的样子从而能够最终帮助保护应用程序的完整性和安全性并且由此纠正许多ASP开发人员—特别是ASP管理人员都在反映的一个共同的抱怨/担心)
使用定制错误页面
虽然我们发送给用户的公用错误信息是安全的就是说它不会威胁到应用程序的秘密但是这样的信息并不好看也许你希望用户永远也看不到这样的信息相反当处理请求的过程中如果发生了一个为处理的错误你希望能够显示自己的定制错误页面显示出自己的品牌以及特定的错误信息
向ASPNET 应用程序中增加定制错误信息非常容易首先编写自己的 web页面它可以是任何类型的文件aspxasp等等然后在应用程序的configweb文件中修改配置信息让它指向这个文件
举例说明以下这个配置信息说明在发生了任何未能预定处理错误的情况下浏览器都应该被重定向到ErrorPageaspx页面
<configuration>
<customerrors mode=remoteonly defaultredirect=ErrorPageaspx />
</configuration>
<customerrors>
标记中的defaultredirect属性定义了在发生错误的情况下用户将被重定向到的默认页面或者也可以根据响应的http代码状态重定向到其它的页面来覆盖这个默认值例如重定向到一个特殊的未找到文件错误页面非法访问错误页面服务器沖突错误页面等等
举例说明以下的配置信息覆盖个特定的http 状态代码所有其它错误都返回到一个默认页面
<customerrors defaultredirect=x mode=remoteonly>
<error statuscode= redirect= />
<error statuscode= redirect= />
<error statuscode= redirect= />
</customerrors>
在定制错误页面上有一件事我们已经遇到过那就是虽然它们对于已经完成的情况非常有用然而在开发过程中却非常难以对付因为你预想到在开发过程中会有bug并且当你发现的时候真的希望看到实际的错误信息跟蹤为了解决这个问题<customerrors>标记支持一个有个值的mode属性
on意思是总是发出定制错误页面
off意思是从不发出定制错误页面(你总是看到原始的错误信息)
remoteonly意思是只有当远程浏览器点击站点时才发出定制错误页面(而在实际机器上点击站点的开发人员看到的是详细的错误信息)
装备应用程序帮助管理员跟蹤错误
虽然向客户显示定制的错误信息是一件好事但也许你还是希望当一个错误在站点上发生时开发人员和管理员能够很容易地实时发现它并且识别出是什么问题url及例外信息是什么
为了解决这个问题ASPNET引入了一个可以在Globalasax文件中处理的新的应用程序层事件Application_Error在处理一个web请求的过程中当有一个未处理的例外发生时这个方法就被调用开发人员从中可以获得有关请求的特殊信息例如要弹出页面的url查询字符串变量用户代理cookie的值等等以及封装错误信息的实际例外对象的信息然后就可以继续进行运行任何他们想要跟蹤以及用来通知管理员和开发人员有关问题的逻辑这可能包括使用 SystemDiagnostic APIs向NET事件日志写入信息使用SystemWebUtil SMTP Email APIs向管理员发email向一个数据库中写入信息等等
举例说明以下的Globalasax文件演示了如何向一个定制NT事件日志MyCustomLog写入错误信息包括页面url和例外堆栈记录
<%@ Import Namespace=SystemDiagnostics %>
<script language=VB runat=server>
Sub Application_Error(Sender As Object E as EventArgs)
Obtain the URL of the Request
Dim PageUrl as String = RequestPath
Obtain the Exception Object for the Error
Dim ErrorInfo as Exception = ServerGetLastError()
Construct Error Message to Write to NT Event Log
Dim Message As String = Url & PageUrl
Message = Message & Error:
Message = Message & ErrorInfoToString
NT Event Log Name to Write Message To
Dim LogName As String = MyCustomLog
Create Event Log if It Doesnt Exist
If (Not EventLogSourceExists(LogName)) Then
EventLogCreateEventSource(LogName LogName)
End if
Fire off to Event Log
Dim Log as New EventLog
LogSource = LogName
LogWriteEntry(Message EventLogEntryTypeError)
End Sub
</script>
要想看到上门所描述的一切实际是如何工作的试着在机器上创建一个新的IIS应用程序vroot然后将上面的样本代码复制到一个新的Globalasax文件中这个文件是在应用程序根目录中创建的然后将以下代码片段复制/粘贴到Blowupaspx文件中:
<html>
<body>
<%
Dim x
xBlowUp()
%>
</body>
</html>
注意这个文件总是会引起一个运行时间错误因为其中引起了一个无效引用例外而x对象根本就没有创建也没有Blowup方法因此当你用浏览器点击页面将看到一个错误信息时
除了在浏览器内看到错误信息外由于Globalasax内部存在Application_Error事件你还会在NT 事件日志中看到它要查看这点请选择开始菜单>程序>管理工具>事件查看器然后点击右侧的MyCustomLog节点就会显示出日志的内容在其内部特定项目上双击就可以看到页面的url以及堆栈的记录细节
注意NT事件日志可以远程查看因此这是一个从远处跟蹤机器状态的简便方法还要注意当你动态创建一个新的NT事件日志时为了看到它在列表中显示出来必须每次都退出并重新启动NT事件查看器
既然当新的ASPNET 应用程序内部发生问题时我们能够轻松地跟蹤错误的细节现在我们就要确保我们的客户所看到的只是友好的定制错误信息这就要在vroot中创建一个CustomErroraspx页面
<html>
<body>
<h> My Custom Error Page</h>
<h> Todo: Make this pretty </h>
</body>
</html>
然后修改configweb文件让它指向这个页面
<configuration>
<customerrors mode=on defaultredirect=CustomErroraspx/>
</configuration>
这时请再次点击BlowUpaspx页面你会看到浏览器被自动重定向到友好的错误页面如果你查看NT事件日志的话会看到关于这个错误对一个管理员进行通知时必要的所有细节以及开发人员要识别和修复它所必要的所有细节
要注意由于客户信息信息被存储在configweb 文件而不是IIS元数据中因此它可以通过xcopied进行安装而不需要请求用户使用IIS Admin 工具ASPNET的这种客户定制功能在IIS 和IIS中也同样奏效