在ASP.NET MVC中,通过应用程序生命周期中的Application_Error事件可以捕获到网站引发的所有未处理异常。本文作为学习笔记,记录了使用Global.asax文件的Application_Error事件处理和捕获全局异常的详细步骤。

文章演示项目是使用vs2013编译器编写的,下载地址:GlobalExceptionHandle-By-Application_Error.zip。

在VS2013中新建一个MVC项目,这里要先关闭自定义错误,将Web.config配置文件中customErrors节点的mode设置为Off,注意大小写:

  <system.web>
<customErrors mode="Off"></customErrors>
<compilation debug="true" targetFramework="4.5"/>
<httpRuntime targetFramework="4.5"/>
</system.web>

在GlobalFilter全局过滤器中取消HandleErrorAttribute的注册:

public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//filters.Add(new HandleErrorAttribute());
}
}

打开Global.asax文件并添加Application_Error事件代码:

protected void Application_Error(Object sender, EventArgs e)
{
Exception lastError = Server.GetLastError();
if (lastError != null)
{
//异常信息
string strExceptionMessage = string.Empty; //对HTTP 404做额外处理,其他错误全部当成500服务器错误
HttpException httpError = lastError as HttpException;
if (httpError != null)
{
//获取错误代码
int httpCode = httpError.GetHttpCode();
strExceptionMessage = httpError.Message;
if (httpCode == || httpCode == )
{
Response.StatusCode = ;
//跳转到指定的静态404信息页面,根据需求自己更改URL
Response.WriteFile("~/HttpError/404.html");
Server.ClearError();
return;
}
} strExceptionMessage = lastError.Message; /*-----------------------------------------------------
* 此处代码可根据需求进行日志记录,或者处理其他业务流程
* ---------------------------------------------------*/ /*
* 跳转到指定的http 500错误信息页面
* 跳转到静态页面一定要用Response.WriteFile方法
*/
Response.StatusCode = ;
Response.WriteFile("~/HttpError/500.html"); //一定要调用Server.ClearError()否则会触发错误详情页(就是黄页)
Server.ClearError();
Server.Transfer("~/HttpError/500.aspx");
}
}

从上面的演示代码可以看出,在Application_Error事件中可以通过Server.GetLastError()获取Exception对象,并依据Exception对象获取相关异常信息,包括HTTP错误码、详细的错误信息等等。在事件中可以根据需求编写自己的业务代码,比如记录日志、跳转到自定义的错误页面等。

编写Application_Error事件的代码需要注意的地方

1、一定要取消GlobalFilter全局过滤器中HandleErrorAttribute的注册,也要注意检查项目中是否有其他全局过滤器对异常进行处理的,防止HTTP 500类型的服务器错误不会触发Application_Error事件(其他类型错误依然可触发)。

此外也可以关闭Web.config配置文件的自定义错误:<customErrors mode="Off"></customErrors>。因为一般情况下都是在Application_Error事件中处理要跳转的自定义错误页,这样有利于设置HTTP错误代码。


2、无论最终处理的流程如何,在流程结束或者响应输出的地方,一定要调用Server.ClearError()方法清空异常,否则异常错误依然处于未被处理的状态,如果customErrors mode="On",那么异常会被自定义错误模块处理,除非本意就是要使用这种方式跳转到错误页。

如果已经关闭了自定义错误但又没有调用ClearError方法,将会引发ASP.Net的详细错误页面(俗称黄页)。


3、如果要跳转到静态的自定义错误页面中,请使用Response.WriteFile(string filename)方法,最后设置下HTTP状态码,比如下面的代码:

//跳转到指定的静态404信息页面,根据需求自己更改URL
Response.WriteFile("~/HttpError/404.html");
Server.ClearError();

4、如果想要使用Server.Transfer(string path)方法跳转到自定义的错误页面,这里有两点需要注意:

第一点、一定不能设置HTTP状态码(Response.StatusCode),否则会引发IIS错误,无论是跳转到静态还是动态页面中。例如下列代码:

//Response.StatusCode = 500;
//Server.Transfer("~/HttpError/500.html");
//Server.Transfer("~/HttpError/500.aspx");

第二点、Server.Transfer方法对路由地址不兼容,会引发错误,下面代码使用路由会引发另一个异常:

Server.Transfer("~/Home/Index");

使用应用程序全局错误的一些优势:

第一点就是兼容性好,Web Form和MVC中都可以通用,如果旧的Web Form项目中是使用Application_Error处理全局异常,那么在新的MVC项目就可以很容易移植过来!此外灵活性也比较高,相比ASP.NET自带的自定义错误以及MVC的HandleError特性,可以更加自由的编写灵活的业务代码。

另外可以根据需求设定HTTP错误码,这方面也是考虑到一个SEO的问题,毕竟ASP.NET的自定义错误机智是使用302重写跳转,并不有利于SEO。虽然customErrors节点的redirectMode属性可以设置为"ResponseRewrite"(重写),但是如果在跳转的页面上不设置HTTP错误码,则HTTP状态码为200。

Application_Error处理网站异常的局限性

Application_Error事件无法处理已经被处理的异常,比如在try-catch捕捉的异常。此外由于是应用程序级别的事件,所以无法处理操作方法或者控制器级别的异常,暂时我也只想到这些局限,一般来说只要项目没有什么特殊要求都可以使用此事件处理自定义异常。

以上文章剽窃自:http://shiyousan.com/post/635813858052755170

ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常的更多相关文章

  1. ASP.NET MVC中的Global.asax文件

    1.global.asax文件概述 global.asax这个文件包含全局应用程序事件的事件处理程序.它响应应用程序级别和会话级别事件的代码. 运行时, Global.asax 将被编译成一个动态生成 ...

  2. 在ASP.Net MVC 中,如何在Global.asax中配置一个指向Area内部的默认Route

    ASP.Net MVC 中配置Route的时候可以设置一个默认的Route. 比如我要在输入http://localhost的时候默认进入http://localhost/home/index.可以在 ...

  3. Asp.net Mvc中利用ValidationAttribute实现xss过滤

    在网站开发中,需要注意的一个问题就是防范XSS攻击,Asp.net mvc中已经自动为我们提供了这个功能.用户提交数据时时,在生成Action参数的过程中asp.net会对用户提交的数据进行验证,一旦 ...

  4. Asp.net MVC中Route的理解

    在Asp.net MVC中,对于一个请求,是通过路由找到对应的Controller类中的对应Action,并与model进行交互,最后返回到view. 就是说Asp.net MVC是用Route来定义 ...

  5. ASP.NET MVC中Area的另一种用法

    ASP.NET MVC中Area的另一种用法 [摘要]本文只是为一行代码而分享 context.MapRoute("API", "api/{controller}/{ac ...

  6. IOC 容器在 ASP.NET MVC 中的应用

    IOC 容器在 ASP.NET MVC 中的应用 IOC:Inversion Of Control 翻译为控制反转,我们在面向对象软件开发过程中,一个应用程序它的底层结构可能由N种不同的构件来相互协作 ...

  7. ASP.NET MVC中使用Ninject

    ASP.NET MVC中使用Ninject 在[ASP.NET MVC 小牛之路]系列上一篇文章(依赖注入(DI)和Ninject)的末尾提到了在ASP.NET MVC中使用Ninject要做的两件事 ...

  8. ASP.NET MVC中的Session以及处理方式

    最近在ASP.NET MVC项目中碰到这样的情况:在一个controller中设置了Session,但在另一个controller的构造函数中无法获取该Session,会报"System.N ...

  9. 转载ASP.NET MVC中Session的处理机制

    本文章转载自 http://www.cnblogs.com/darrenji/p/3951065.html ASP.NET MVC中的Session以及处理方式   最近在ASP.NET MVC项目中 ...

随机推荐

  1. latex 双引号 “

    别在latex敲,在记事本上敲完后,拷贝到latex中.

  2. rewind()函数

    函数名: rewind功 能: 将文件指针重新指向一个流的开头用 法: int rewind(FILE *stream);程序例: #include <stdio.h>#include & ...

  3. Microsoft Windows CVE-2017-8464 LNK 远程代码执行漏洞(复现)

    2017年6月13日,微软官方发布编号为CVE-2017-8464的漏洞公告,官方介绍Windows系统在解析快捷方式时存在远程执行任意代码的高危漏洞,黑客可以通过U盘.网络共享等途径触发漏洞,完全控 ...

  4. python对象继承

    继承允许我们在两个或者更多的类之间创建一种“是一个”的关系,这种关系把共同的细节抽象到一个超类里. 从技术上讲,每一个我们创建的类都使用了继承,所有的python类都是一个叫做object的特殊类的子 ...

  5. Dubbo管控台安装(zookeeper集群)

    Dubbo管控台可以对注册到zookeeper注册中心的服务或服务消费者进行管理,但管控台是否正常对Dubbo服务没有影响,管控台也不需要高可用,因此节点部署   环境:Centos6.6.IP:10 ...

  6. js中数值类型相加变成拼接字符串的问题

    如题,弱类型计算需要先进行转型,例: savNum=parseInt(savNum)+parseInt(num);或者使用 number()转型

  7. css的几个小技巧

    本文收录css设置样式的一些小技巧 1. 设置文字在块级标签居中(包括水平居中和垂直居中) 水平居中 方法一:使用text-align text-align:center 方法二:目标标签的父级标签设 ...

  8. SpringBoot系列: 理解 Spring 的依赖注入(二)

    ==============================Spring 容器中 Bean 的名称==============================声明 bean 有两个方式, 一个是 @B ...

  9. VS Code使用 Vue工程配置 eslint

    首先确保VS Code 安装了 Vetur 和 Eslint 插件. VS CODE :文件 =>首选项 => 设置   (有3个点 或 {} 这样的大括号,打开setting.json) ...

  10. C# string 保留数字英文字母

    using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressi ...