对于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. C#关于导出excel的方法

    一说到导出excel可能很多人都会觉得说直接利用npoi 导入导出excel格式的文件,那样非常方便,但是可能有些时候有的浏览器不支持,那么该怎么办呢,现在介绍一种纯C#的导出excel的方法,代码如 ...

  2. MVC 与 webform比较

    来自:http://www.cnblogs.com/xiaozhi_5638/p/4019065.html ASP.NET Webforms Behind Code的好处和存在的问题 ASP.NET ...

  3. Linux (Ubuntu) 下配置VPN服务器

    昨天网上找了下VPN的相关信息,居然各种撞墙,特别郁闷,自己不容易找到的东西,记录下VPN的配置信息 ubuntu 13.1下配置VPN  ,采用PPTP实现, 第一步.安装pptpd,没有安装包记得 ...

  4. ORM原型概念

    ORM[Object-Relation-Mapping]对象关系映射. 这个名词已经出来好几年了.已经不陌生.  以前在项目中针对相对复杂业务逻辑时一般采用领域模型驱动方式进行业务概述,分析和建模. ...

  5. linux shell 指令 诸如-d, -f, -e之类的判断表达式

    文件比较运算符-e filename 如果 filename存在,则为真 [ -e /var/log/syslog ]-d filename 如果 filename为目录,则为真 [ -d /tmp/ ...

  6. 谈谈UIView的几个layout方法

    谈谈UIView的几个layout方法-layoutSubviews.layoutIfNeeded.setNeedsLayout...   最近在学习swift做动画,用到constraint的动画, ...

  7. 安装生物信息学软件-Biopython

    其实好多东西装过好多次,然而每次都要翻文档,经常掉进前面掉进过的坑...所以这里重新写一份指南,以防下次再装又忘了(魂淡我并不想再装了啊不要立flag) 1. 安装biopython 1.1 因为bi ...

  8. easyui js基础

    $(document).ready( function(){ initload(); });function initConfig(){ //数据列表 yzfymx=$("#tjdj&quo ...

  9. apt-get命令详解

    apt-cache search # ------(package 搜索包) apt-cache show #------(package 获取包的相关信息,如说明.大小.版本等) sudo apt- ...

  10. USB协议-USB的描述符及其之间的关系

    USB只是一个总线,只提供一个数据通路而已.USB总线驱动程序并不知道一个设备具体如何操作,有哪些行为.具体的一个设备实现什么功能,要由设备自己来决定.那么,USB主机是如何知道一个设备的功能以及行为 ...