对于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. Js 冒泡事件阻止

    Js 冒泡事件阻止   1. 事件目标 现在,事件处理程序中的变量event保存着事件对象.而event.target属性保存着发生事件的目标元素.这个属性是DOM API中规定的,但是没有被所有浏览 ...

  2. oracle数据库的乱码问题解决方案

    我的电脑-----高级系统设置----高级-----环境变量 LANG=zh_CN.GBK NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

  3. .htaccess语法中RewriteCond和RewriteRule意义

    今天看了301重定向设置的方法,对网站的首页权重有较重要意义.于是看了别人写的.htaccess文件发现一头雾水,于是查了一些资料来进一步理解. RewriteCond语法 RewriteCond T ...

  4. Documentum常见问题11-xplore全文检索时找不到相关内容

    最近帮助同事处理了一个关于全文检索的问题,随手记录下来供以后参考. 问题一 某些Cabinet下的文件可以全文检索到,但某些Cabinet下的数据全文检索不成功. 新建了一个Docbase-AADCT ...

  5. IT公司100题-28-整数的二进制表示中1的个数

    问题描述: 输入一个整数n,求n的二进制表示中,一共有多少个1.例如n=8,二进制表示为00001000,二进制表示中有1个1.     分析: 如果一个数n不为0,那么n-1的二进制表示,与n的二进 ...

  6. NOIP 2015 BZOJ 4326 运输计划 (树链剖分+二分)

    Description 公元 年,人类进入了宇宙纪元. L 国有 n 个星球,还有 n− 条双向航道,每条航道建立在两个星球之间,这 n− 条航道连通了 L 国的所有星球. 小 P 掌管一家物流公司, ...

  7. CPU寄存器

    CPU寄存器主要的有 CS:IP这是代码段,主要是执行代码的: SS:SP这是栈段,很多时候数据都要用它, ds:si,这是一个数据段, 还有一个标志寄存器flag,中断的时候要保存它的信息,以便中断 ...

  8. Oracle日期时间

    今天上班一个问题:sql获取最近三天内上传文档在页面显示标记new,超过三天则不显示标记,并且在标题标明new数量. 完成思路:sql上加一字段查询出三天内为1,其他为非1;在angularJs的se ...

  9. UVa 1626 Brackets sequence (动态规划)

    题意:用最少的括号将给定的字符串匹配,输出最优解.可能有空行. 思路:dp. dp[i][j]表示将区间i,j之间的字符串匹配需要的最少括号数,那么 如果区间左边是(或[,表示可以和右边的字符串匹配, ...

  10. JM8.6学习

    1. vs2010 设置参数 编译运行JM8.6 (参考http://bbs.chinavideo.org/forum.php?mod=viewthread&tid=15695&hig ...