在ASP.NET MVC中,我们可以使用HandleErrorAttribute特性来具体指定如何处理Action抛出的异常.只要某个Action设置了 HandleErrorAttribute特性,那么默认的,当这个Action抛出了异常时MVC将会显示Error视图,该视图位于~/Views /Shared目录下.
可以通过设置下面这些属性来更改HandleErrorAttribute特性的默认处理:
如果某个Action设置了多个HandleErrorAttribute,Order属性可以用来确定使用哪个过滤器.其值可以设置为从-1(最高优先级)到任何正整数之间的整数来标识其优先级,值越大,优先级别越低.Order属性遵循以下规则:
ASP.NET MVC框架将异常信息存储在ViewDataDictionary中来传递给Error视图,该ViewDataDictionary的Model属性即是ExceptionContext类的一个实例,这个ViewData有下面几个键:
ActionName:目标Action方法的名称
ControllerName:目标Controller的名称
Exception:异常对象.
下面我们来开启用于HandleErrorAttribute过滤器的自定义错误处理,打开程序的Web.config文件,在system.web节中加入一个customErrors元素,如下所示
有时候在Error视图中也会发生错误,这时ASP.NET将会显示其默认的错误页面(黄底红字),为了避免这种情况的出现,我们在Web.config文件的customErrors节中来自定义错误页面,如下:
下面的示例说明了如何对Controller和Action应用HandleErrorAttribute特性来自定义异常处理.
示例中HomeController有一个名为ThrowException的Action方法,在该Action中将会抛出一个 ApplicationException类型的错误,这个Action应用了HandleErrorAttribute,但是没有设置任何参数.当该 Action执行时将会抛出一个异常,显示默认的Error视图.
而ThrowNotImplemented方法则应用了设有两个参数的HandleErrorAttribute,View参数指定了自定义的 Error视图名称:CustomErrorView,ExceptionType参数指定了该过滤器仅处理ThrowNotImplemented类型 的异常.
Controller的HandleErrorAttribute则设置了Order参数为2,意味着该过滤器只会被在Index或About方法产生异常时执行.
同时示例给出了视图CustomErrorView和CustomError.Master的内容.
视图CustomErrorView显示异常的信息,比如抛出异常的Controller和Action的名称,异常的内容以及堆栈跟踪信息.
视图Index上有两个链接,分别指向了ThrowException和ThrowNotImplemented两个Action.
HomeController类
视图 CustomErrorView
视图 Index
母版页 CustomError.Master
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="http://www.cnblogs.com/Content/Site.css" rel="stylesheet" type="text/css" />
<style type="text/css">
body.error
{
background-color: Maroon;
color: #696969;
}
</style>
</head>
<body class="error">
<div class="page">
<div id="header">
<div id="title">
<h1>A Custom Error Occurred</h1>
</div>
<div id="logindisplay">
<% Html.RenderPartial("LogOnUserControl"); %>
</div>
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About", "About", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
</div>
</div>
</div>
</body>
</html>