对于Asp.Net MVC 项目中,对于异常情况下,会跳转到自己定义好的页面,这时就用到了MVC中的异常过滤器(Exception Filters

(1)一旦action 方法中出现异常,异常过滤器就会控制程序的运行过程,开始内部自动写入运行的代码。MVC为我们提供了编写好的异常过滤器:HandeError。

(2)当action方法中发生异常时,过滤器就会在“~/Views/[current controller]”或“~/Views/Shared”目录下查找到名称为”Error”的View,然后创建该View的ViewResult,并作为响应返回。

一些配置信息

1、在WebConfig中把过滤器配置启动

当自定义异常被捕获时,异常过滤器变为可用。为了能够获得自定义异常,打开Web.config文件,在System.Web.Section下方添加自定义错误信息。

<customErrors mode="On">
</customErrors>

2、创建Error View

在“~/Views/Shared”文件夹下,会发现存在“Error.cshtml”文件,该文件是由MVC 模板提供的,如果没有自动创建,该文件也可以手动完成。

3、绑定异常过滤器

将过滤器绑定到action方法或controller上,不需要手动执行,打开 App_Start folder文件夹中的 FilterConfig.cs文件。在 RegisterGlobalFilters 方法中会看到 HandleError 过滤器已经以全局过滤器绑定成功。

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

默认是启动全局过滤器的,也可以删除全局过滤器,那么会将过滤器绑定到action 或controller层,但是不建议这么做,最好是在全局中

        [HandleError(ExceptionType = typeof(NullReferenceException), View = "error")]
public ActionResult Index()
{
throw new NullReferenceException();
return View();
}

4、运行过后,在View中显示错误信息

将Error View转换为HandleErrorInfo类的强类型View,并在View中显示错误信息。

@model HandleErrorInfo
@{
Layout = null;
} <!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width" />
<title>错误</title>
</head>
<body>
<hgroup>
<h1>错误。</h1>
<h2>处理你的请求时出错。1231321</h2>
</hgroup>
错误信息:@Model.Exception.Message<br />
控制器:@Model.ControllerName <br />
方法: @Model.ActionName
</body>
</html>

5、运行测试,报错后,显示的页面如下图为:

另外还有种情况,就是Handle error属性能够确保无论是否出现异常,自定义View都能够显示,但是它的能力在controller和action 方法中是受限的。不会处理“Resource not found”这类型的错误。

比如,运行应用程序时,输入一些奇怪的URL

针对这种情况,

(1)我们需要在WebConfig中添加这样一个配置

    <customErrors mode="On">
<error statusCode="404" redirect="~/Error/Index"/>
</customErrors>

(2)创建ErrorController控制器,并创建Index方法,代码如下:

    [AllowAnonymous]
public class ErrorController : Controller
{
public ActionResult Index()
{
Exception e = new Exception("Invalid Controller or/and Action Name");
HandleErrorInfo eInfo = new HandleErrorInfo(e, "Unknown", "Unknown"); return View("Error", eInfo);
}
}

[AllowAnonymous]

将AllowAnonymous属性应用到 ErrorController中,因为错误控制器和index方法不应该只绑定到认证用户,也很有可能用户在登录之前已经输入错误的URL。

这样混乱URL的出现的报错信息就跳转到指定的页面了。

接下来的情况,扩展Handler Error,并进行添加日志处理

(1)在根目录下,新建文件夹,命名为Logger。在Logger 文件夹下新建类 FileLogger

    public class FileLogger
{
public void LogException(Exception e)
{ File.WriteAllLines("C://Error//" + DateTime.Now.ToString("yyyy-MM-dd mm hh ss") + ".txt",
new string[]
{
"Message:"+e.Message,
"Stacktrace:"+e.StackTrace
});
}     
        public void LogExceptionContext(ExceptionContext filterContext)
{
File.WriteAllLines("C://Error//" + DateTime.Now.ToString("yyyy-MM-dd mm hh ss") + ".txt",
new string[]
{
"时间:"+DateTime.Now.ToString("yyyy-MM-dd mm hh ss"),
"ip地址:"+filterContext.HttpContext.Request.UserHostAddress,
"控制器:"+filterContext.RouteData.Values["Controller"],
"动作方法:"+filterContext.RouteData.Values["Action"],
"错误信息:"+filterContext.Exception.Message+">>>"+filterContext.Exception.StackTrace
});
}

    }

(2)创建CommonExceptionFilter类

在 Filters文件夹下,新建 EmployeeExceptionFilter类,继承 HandleErrorAttribute类,重写 OnException方法:

    public class CommonExceptionFilter : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
FileLogger logger = new FileLogger(); logger.LogException(filterContext.Exception);
base.OnException(filterContext); filterContext.ExceptionHandled = true;
}
}

(3)修改默认的异常过滤器

在FilterConfig中进行修改

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

这样运行,报错的时候,会在C盘下面记录报错的日志。

需要注意的是 filterContext.ExceptionHandled = true;

当返回自定义响应时,做的第一件事情就是通知MVC 引擎,手动处理异常,因此不需要执行默认的操作,不会显示默认的错误页面。

使用filterContext.ExceptionHandled = true;这句话即可实现页面的显示。

另外,我们可以在OnException这个重写方法中加上 ExceptionHandled属性

        public override void OnException(ExceptionContext filterContext)
{
if (!filterContext.ExceptionHandled)
{
FileLogger logger = new FileLogger(); logger.LogException(filterContext.Exception);
base.OnException(filterContext); filterContext.ExceptionHandled = true;
}
}

我们这里还判断了ExceptionHandled属性,这个属性的含义是如果其他的异常过滤器已经处理了该异常,则该属性的值为true,为了能够适应大的范围,所以笔者这里建议读者也要先判断是否已经有其他的异常过滤器已经处理过这个异常了。

Asp.net MVC 之异常处理的更多相关文章

  1. ASP.NET MVC统一异常处理

    前言: 今早看了篇文章:求知成瘾,却无作品 的思考:很有感触,发现原来自己也是这样,对每样东西都抱有很大的兴趣或者希望自己去学,一年后发现原来自己什么都是皮毛什么都不精!最终发现真正的大牛都是在某一个 ...

  2. ASP.NET MVC自定义异常处理

    1.自定义异常处理过滤器类文件 新建MyExceptionAttribute.cs异常处理类文件

  3. Asp.net MVC 自定义异常处理类

    using ElegantWM.Common; using System; using System.Collections.Generic; using System.Linq; using Sys ...

  4. 七天学会ASP.NET MVC (六)——线程问题、异常处理、自定义URL

    本节又带了一些常用的,却很难理解的问题,本节从文件上传功能的实现引出了线程使用,介绍了线程饥饿的解决方法,异常处理方法,了解RouteTable自定义路径 . 系列文章 七天学会ASP.NET MVC ...

  5. ASP.NET MVC异常处理

    ASP.NET MVC异常处理方案 如何保留异常前填写表单的数据 ASP.NET MVC中的统一化自定义异常处理 MVC过滤器详解 MVC过滤器使用案例:统一处理异常顺道精简代码 ASP.NET MV ...

  6. Asp.net Mvc 身份验证、异常处理、权限验证(拦截器)实现代码

    本问主要介绍asp.net的身份验证机制及asp.net MVC拦截器在项目中的运用.现在让我们来模拟一个简单的流程:用户登录>权限验证>异常处理 1.用户登录 验证用户是否登录成功步骤直 ...

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

    当ASP.NET MVC程序出现了异常,怎么处理更加规范? 1. 最简单的方法是设置<customErrors/>节点 <customErrors>节点用于定义一些自定义错误信 ...

  8. ASP.NET MVC异常处理方案

    异常处理是每一个系统都必须要有的功能,尤其对于Web系统而言,简单.统一的异常处理模式尤为重要,当打算使用ASP.NET MVC来做项目时,第一个数据录入页面就遇到了这个问题. 在之前的ASP.NET ...

  9. ASP.NET MVC开发:Web项目开发必备知识点

    最近加班加点完成一个Web项目,使用Asp.net MVC开发.很久以前接触的Asp.net开发还是Aspx形式,什么Razor引擎,什么MVC还是这次开发才明白,可以算是新手. 对新手而言,那进行A ...

随机推荐

  1. OpenBSD为何还在用CVS之感

    一个轻松无聊的晚上突然想到一个问题——在当今这个Git大红大紫的时代,OpenBSD为何还在用CVS代码仓库?连他同阵营的FreeBSD都已经改用SVN,宣布逐渐废掉CVS了……问了下google,搜 ...

  2. c#调用c++动态链接库的问题

    1. Server Error in '/' Application. Object reference not set to an instance of an object. 这个问题是接口中的方 ...

  3. JS js与css的动态加载

    http://www.cnblogs.com/zhuimengdeyuanyuan/archive/2013/03/06/2946277.html

  4. NOIP2014提高组 酱油记

    NOIP考到哪里我就写到哪里好了. 2014/10/12 初赛 下午两点半开始考,我两点就到了.然后看到了QYL,NYZ,CZR等大神,先Orz了再说. 考试开始前,发现考场竟然没几个我认识的,不是按 ...

  5. linux 基本命令操作

    1.ls 命令 ls -a  列出所有文件,包括隐藏文件 ls -l  列出文件详细信息 ls -r 列出所有文件包括文件夹 查询具体文件可以在命令后面加  |grep 要匹配的字符串,方便我们查找, ...

  6. javaee包含的服务和组件

    参考自 http://blog.itpub.net/29990276/viewspace-1318551/

  7. c# mvc使用 npoi下载 excel

    IWorkbook book = new NPOI.HSSF.UserModel.HSSFWorkbook(); //添加一个sheet ISheet sheet1 = book.CreateShee ...

  8. 安装64位mysql5.626

    计算机--右击属性--左上高级系统变量---环境变量 path 添加 mysql 的bin目录 ;D:\mysqlwinx64\bin1 //mysql 5.6.26安装前先解压到d盘根目录 cd D ...

  9. Java - 简单的对象排序 - Comparator

    注:对象排序,就是对对象中的某一字段进行比较,以正序或倒序进行排序. 例: 需要排序的对象: public class Person { public int age; public String n ...

  10. SQL升级脚本实现按版本差异化升级(优化)

    1.增加了对SQL Server 2000的兼容: 2.支持对脚本目录的批量处理: 3.将脚本版本的判断放到具体的升级子脚本中去,让调度脚本更固化. -- 根据SQL的版本好确定启用xp_cmdshe ...