在ASPNET MVC中我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常只要某个Action设置了HandleErrorAttribute特性那么默认的当这个Action抛出了异常时MVC将会显示Error视图该视图位于~/Views/Shared目录下
设置HandleError属性
可以通过设置下面这些属性来更改HandleErrorAttribute特性的默认处理:
ExceptionType指定过滤器处理那种或哪些类型的异常如果没有指定该属性过滤器将会处理所有的异常
View指定发生异常时过滤器要显示的视图名称
Master指定视图母版的名称如果有的话
Order指定过滤器应用的顺序如果一个Action有多个HandleErrorAttribute过滤器
指定Order属性
如果某个Action设置了多个HandleErrorAttributeOrder属性可以用来确定使用哪个过滤器其值可以设置为从(最高优先级)到任何正整数之间的整数来标识其优先级值越大优先级别越低Order属性遵循以下规则:
应用到Controller上的过滤器将会自动应用到该Controller的所有Action上
如果Controller和Action都应用了HandleErrorAttribute那么只要Order属性值相同将会先执行Controller上的过滤器而后才会执行Action上的过滤器
对于相同Order属性的过滤器其执行先后次序不定
如果没有指定Order属性则默认为这意味着该过滤器将比其他的过滤器优先执行除非其他过滤器指定了Order为
如果有多个过滤器可适用那么第一个可以处理该异常的过滤器会被首先调用然后针对该异常的处理将会终结
在View中获取异常信息
ASPNET MVC框架将异常信息存储在ViewDataDictionary中来传递给Error视图该ViewDataDictionary的Model属性即是ExceptionContext类的一个实例这个ViewData有下面几个键:
ActionName:目标Action方法的名称
ControllerName:目标Controller的名称
Exception:异常对象
启用自定义错误处理
下面我们来开启用于HandleErrorAttribute过滤器的自定义错误处理打开程序的nfig文件在systemweb节中加入一个customErrors元素如下所示
<systemweb>
<customErrors mode=On defaultRedirect=Error />
</systemweb>
处理Error视图中的错误
有时候在Error视图中也会发生错误这时ASPNET将会显示其默认的错误页面(黄底红字)为了避免这种情况的出现我们在nfig文件的customErrors节中来自定义错误页面如下:
<systemweb>
<customErrors mode=On defaultRedirect=>
<error statusCode= redirect=/ />
</customErrors>
</systemweb>
示例程序
下面的示例说明了如何对Controller和Action应用HandleErrorAttribute特性来自定义异常处理
示例中HomeController有一个名为ThrowException的Action方法在该Action中将会抛出一个ApplicationException类型的错误这个Action应用了HandleErrorAttribute但是没有设置任何参数当该Action执行时将会抛出一个异常显示默认的Error视图
而ThrowNotImplemented方法则应用了设有两个参数的HandleErrorAttributeView参数指定了自定义的Error视图名称:CustomErrorViewExceptionType参数指定了该过滤器仅处理ThrowNotImplemented类型的异常
Controller的HandleErrorAttribute则设置了Order参数为意味着该过滤器只会被在Index或About方法产生异常时执行
同时示例给出了视图CustomErrorView和CustomErrorMaster的内容
视图CustomErrorView显示异常的信息比如抛出异常的Controller和Action的名称异常的内容以及堆栈跟蹤信息
视图Index上有两个链接分别指向了ThrowException和ThrowNotImplemented两个Action
HomeController类
[HandleError(Order = )]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData[Message] = Welcome to ASPNET MVC!;
return View();
}
public ActionResult About()
{
return View();
}
[HandleError]
public ActionResult ThrowException()
{
throw new ApplicationException();
}
[HandleError(View = CustomErrorView ExceptionType = typeof(NotImplementedException))]
public ActionResult ThrowNotImplemented()
{
throw new NotImplementedException();
}
}
视图 CustomErrorView
<asp:Content ID=Content ContentPlaceHolderID=TitleContent runat=server>
CustomErrorView
</asp:Content>
<asp:Content ID=Content ContentPlaceHolderID=MainContent runat=server>
<h>CustomErrorView</h>
<p>
Controller: <%=((HandleErrorInfo)ViewDataModel)ControllerName %>
</p>
<p>
Action: <%=((HandleErrorInfo)ViewDataModel)ActionName %>
</p>
<p>
Message: <%=((HandleErrorInfo)ViewDataModel)ExceptionMessage %>
</p>
<p>
Stack Trace: <%=((HandleErrorInfo)ViewDataModel)ExceptionStackTrace %>
</p>
</asp:Content>
视图 Index
<asp:Content ID=indexTitle ContentPlaceHolderID=TitleContent runat=server>
Home Page
</asp:Content>
<asp:Content ID=indexContent ContentPlaceHolderID=MainContent runat=server>
<h><%= HtmlEncode(ViewData[Message]) %></h>
<%= HtmlActionLink(Throw An Exception ThrowException)%> (Default Error Page)
<br /><br />
<%= HtmlActionLink(Throw Not Implemented Exception ThrowNotImplemented)%> (Custom Error Page)
</asp:Content>
母版页 CustomErrorMaster
<%@ Master Language=C# Inherits=SystemWebMvcViewMasterPage %>
<!DOCTYPE html PUBLIC //WC//DTD XHTML Transitional//EN transitionaldtd>
<html xmlns= >
<head runat=server>
<title><asp:ContentPlaceHolder ID=TitleContent runat=server /></title>
<link stylesheet type=text/css />
<style type=text/css>
bodyerror
{
backgroundcolor: Maroon;
color: #;
}
</style>
</head>
<body class=error>
<div class=page>
<div id=header>
<div id=title>
<h>A Custom Error Occurred</h>
</div>
<div id=logindisplay>
<% HtmlRenderPartial(LogOnUserControl); %>
</div>
<div id=menucontainer>
<ul id=menu>
<li><%= HtmlActionLink(Home Index Home)%></li>
<li><%= HtmlActionLink(About About Home)%></li>
</ul>
</div>
</div>
<div id=main>
<asp:ContentPlaceHolder ID=MainContent runat=server />
<div id=footer>
</div>
</div>
</div>
</body>
</html>