您当前的位置:首页 > 教学课堂 > .NET技术

ASP.NET MVC中的统一化自定义异常处

来源:长沙北大青鸟  发布时间:2015-07-19  北大青鸟新生QQ群:535324780

 

当ASP.NET MVC程序出现了异常,怎么处理更加规范?

1. 最简单的方法是设置<customErrors/>节点

<customErrors>节点用于定义一些自定义错误信息的信息。此节点有Mode和defaultRedirect两个属性,其中defaultRedirect属性是一个可选属性,表示应用程序发生错误时重定向到的默认URL,如果没有指定该属性则显示一般性错误。Mode属性是一个必选属性,它有三个可能值,它们所代表的意义分别如下: On 表示在本地和远程用户都会看到自定义错误信息。 Off 禁用自定义错误信息,本地和远程用户都会看到详细的错误信息。 RemoteOnly 表示本地用户将看到详细错误信息,而远程用户将会看到自定义错误信息。

这里有必要说明一下本地用户和远程用户的概念。当我们访问asp.net应用程时所使用的机器和发布asp.net应用程序所使用的机器为同一台机器时成为本地用户,反之则称之为远程用户。在开发调试阶段为了便于查找错误Mode属性建议设置为Off,而在部署阶段应将Mode属性设置为On或者 RemoteOnly,以避免这些详细的错误信息暴露了程序代码细节从而引来黑客的入侵。

<error>子节点

在<customErrors>节点下还包含有<error>子节点,这个节点主要是根据服务器的HTTP错误状态代码而重定向到我们自定义的错误页面,注意要使<error>子节点下的配置生效,必须将<customErrors>节点的Mode属性设置为“On”。下面是一个例子:

<customErrors mode="On" defaultRedirect="GenericErrorPage.htm">   

     <error statusCode="403" redirect="403.htm" />   

     <error statusCode="404" redirect="404.htm" />   

</customErrors>  

在上面的配置中如果用户访问的页面不存在就会跳转到404.htm页面,如果用户没有权限访问请求的页面则会跳转到403.htm页面,403.htm和404.htm页面都是我们自己添加的页面,我们可以在页面中给出友好的错误提示。

2. 使用过滤器HandleErrorAttribute

随着ASP.NET MVC版本的更新,出现了HandleErrorAttribute,使用Filter以AOP的思想实现了针对于Action的异常处理。使用此 Filter后,当程序中出现异常的时候,会去封装这些异常信息,然后路由自动转到该Controller对应的Error.cshtml中,如果此路径下没有改文件,则会到shared目录中寻找此文件。另外一个相关的是在Global.asax中的protected void Application_Error[object sender, EventArgs e]方法,是捕捉异常的最后一道防线,也就是说,这是最高层次的异常捕获处理逻辑。使用HandleErrorAttribute后,找到了Error.cshtml,则此时异常已经被捕获处理,所以不会再次被 Application_Error捕获处理。此外,可以通过@model HandleErrorInfo 在Error.cshtml中定制显示异常信息。有一点需要注意的是,HandleErrorAttribute是在customErrors基础之上的,如果想使用 HandleErrorAttribute,customErrors的Mode必须要设置为On或RemoteOnly. 否则,HandleErrorAttribute将不起作用。

3. 自定义显示路径

如果遇到异常后不单单是要自定义异常显示,而且还需要进行日志记录。此时,可以通过继承扩展HandleErrorAttribute来实现新的 Filter,然后在lobal.ascx中对所有的Action进行注册,filters.Add(new MyHandleErrorAttribute()).在这里详细说明一下另一种方式。我们可以写一个专门的Controller和Action来进行异常发生时的路由设置.

1

2

3

4

5

6

7

8

9

10

11

12

public class UtilityController : Controller 

    

        public ActionResult Error() 

        

            return View(); 

        

     

        public ActionResult PageNotFound() 

        

            return View(); 

        

}

当出现异常的时候,把异常抛到最顶端,由Application_Error统一处理。这里的统一处理就包括,记录日志,重新进行页面定向等。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

protected void Application_Error(object sender, EventArgs e) 

        

            var ex = Server.GetLastError(); 

            Log.Error(ex); //记录日志信息 

            var httpStatusCode = (ex is HttpException) ? (ex as HttpException).GetHttpCode() : 500; //这里仅仅区分两种错误 

            var httpContext = ((MvcApplication)sender).Context; 

            httpContext.ClearError(); 

            httpContext.Response.Clear(); 

            httpContext.Response.StatusCode = httpStatusCode; 

            var shouldHandleException = true; 

            HandleErrorInfo errorModel; 

     

            var routeData = new RouteData(); 

            routeData.Values["controller"] = "Utility"; 

     

            switch (httpStatusCode) 

            

                case 404: 

                    routeData.Values["action"] = "PageNotFound"; 

                    errorModel = new HandleErrorInfo(new Exception(string.Format("No page Found", httpContext.Request.UrlReferrer), ex), "Utility", "PageNotFound"); 

                    break; 

     

                default: 

                    routeData.Values["action"] = "Error"; 

                    Exception exceptionToReplace = null; //这里使用了EntLib的异常处理模块的一些功能 

                    shouldHandleException = ExceptionPolicy.HandleException(ex, "LogAndReplace", out exceptionToReplace); 

                    errorModel = new HandleErrorInfo(exceptionToReplace, "Utility", "Error"); 

                    break; 

            

     

            if (shouldHandleException) 

            

                var controller = new UtilityController(); 

                controller.ViewData.Model = errorModel; //通过代码路由到指定的路径 

                ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData)); 

            

        

    }

上一篇文章: ASP 五大高效提速技巧
下一篇文章: 概述ASP.NET Membership
  • 北大青鸟电话
  • 湖南·长沙市岳麓区望城坡望新路334号(汽车西站附近)

    北大青鸟地址

精品IT课程 SERVICEMORE

学士后java工程师课程

北大青鸟java软件开发工程师课程是北大青鸟学士后品牌下的主打课程...
[详细]

学士后.Net工程师课程

北大青鸟.net开发工程师课程采用情景式教学方式,寓教于乐,具有很强的趣味性...
[详细]

ACCP软件工程师课程

ACCP是北大青鸟最经典的一套课程,专门针对18周岁、高中以上学历的人群设计...
[详细]

开班信息 Class InformationMORE

最新班级
课程名称
班级状态
咨询报名
春季特招班
软件工程师
热招
高薪就业班
软件工程师
热招
Accp精英班
软件工程师
热招
Java精英班
学士后Java
热招

长沙市岳麓区大计职业技能培训学校有限公司(支持你成为一个受人尊重的专业人才)

北大青鸟(长沙大计软件学院)(www.csbdqn.com) 是中国IT培训教育(源于北大,师出名门)致力于培养面向软件开发、电商及互联网领域的高端人才,是一家集ACCP软件工程师、网络营销、互联网产品经理、网页设计、Web前端、PHP、 Android、IOS、Java、C/C++等课程为一体的专业培训机构。大计教育与多家企业实体合作,首创“实训教学” 模式,学员在实训课程中,可以直接进入合作企业研发团队,亲自参与项目的运作,真正做到学以致用、学有所成,避免了培训带来的理论与实践脱节的弊端。

咨询电话(08:00-22:00)4008-0731-86 在线客服点击咨询 大计校区官方微信
扫描二维码,即可亲密互动,
更有极致干货等你来拿!
大计校区技术交流群
扫描二维码,即可与各界大神切磋技
术,更多专业老师为你解疑答惑!
24小时免费电话:4008-0731-86
高考 客服 QQ 电话 学费 报名
Top

24小时客服热线

4008-0731-86

0731-82186801

在线咨询问题请点击 在线客服