Asp.net MVC 之异常处理

对于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,为了能够适应大的范围,所以笔者这里建议读者也要先判断是否已经有其他的异常过滤器已经处理过这个异常了。

时间: 2024-08-29 18:43:09

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

ASP.NET MVC自定义异常处理

1.自定义异常处理过滤器类文件 新建MyExceptionAttribute.cs异常处理类文件 MyExceptionAttribute.cs代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace WebApp.Models { public class MyExceptionAttribute : Han

ASP.NET MVC异常处理

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

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

本节又带了一些常用的,却很难理解的问题,本节从文件上传功能的实现引出了线程使用,介绍了线程饥饿的解决方法,异常处理方法,了解RouteTable自定义路径 . 系列文章 七天学会ASP.NET MVC (一)--深入理解ASP.NET MVC 七天学会ASP.NET MVC (二)--ASP.NET MVC 数据传递 七天学会ASP.NET MVC (三)--ASP.Net MVC 数据处理 七天学会ASP.NET MVC (四)--用户授权认证问题 七天学会ASP.NET MVC (五)--L

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

本问主要介绍asp.net的身份验证机制及asp.net MVC拦截器在项目中的运用.现在让我们来模拟一个简单的流程:用户登录>权限验证>异常处理 1.用户登录 验证用户是否登录成功步骤直接忽略,用户登录成功后怎么保存当前用户登录信息(session,cookie),本文介绍的是身份验证(其实就是基于cookie)的,下面看看代码. 引入命名空间 using System.Web.Security; Users ModelUser = new Users() { ID = 10000, Nam

ASP.NET MVC过滤器(一)

MVC过滤器是加在 Controller 或 Action 上的一种 Attribute,通过过滤器,MVC 网站在处理用户请求时,可以处理一些附加的操作,如:用户权限验证.系统日志.异常处理.缓存等.MVC 中包含Authorization filter.Action filter.Result filter.Exception filter 四种过滤器. APS.NET MVC中的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这

源码的说明 ASP.NET MVC 5框架揭秘.zip

第1章 S101 MVP(SC)模式中Presenter与View之间的交互 S102 迷你版的ASP.NET MVC框架 第2章 S201 通过路由实现请求地址与.aspx页面的映射 S202 基本路由注册 S203 在路由注册中指定约束 S204 针对现有物理文件的路由(关闭) S205 针对现有物理文件的路由(开启) S206 RouteCollection和Route的RouteExistingFiles属性对路由的影响 S207 注册需要被忽略的路由地址(未注册) S208 注册需要被

ASP.NET MVC学习之过滤器篇(1)

一.前言 继前面四篇ASP.NET MVC的随笔,我们继续向下学习.上一节我们学习了关于控制器的使用,本节我们将要学习如何使用过滤器控制用户访问页面. 二.正文 以下的示例建立在ASP.NET MVC 4之上(VS2012) 1.授权过滤器 只要涉及用户的网站,都一定会涉及到什么权限的用户可以访问哪个页面.对于新手而言可能都在每个页面中单独写这个功能方法,导致的后果就是大量重复的代码,并且不便于以后的变动.有用一定经验之后,就会采用集中控制的方式,让所有的页面先执行特定的方法去判断,这样的优点就

ASP.NET MVC

[ASP.NET MVC 大牛之路]03 - C#高级知识点概要(2) - 线程和并发 摘要: 我也想过跳过C#高级知识点概要直接讲MVC,但经过前思后想,还是觉得有必要讲的.我希望通过自己的经验给大家一些指引,带着大家一起走上ASP.NET MVC大牛之路,少走弯路.同时也希望能和大家一起交流,这样也能发现我自己的不足,对我自己的帮助也是非常大的.建议大家对C#撑握的不错的时候,可以去看一些...阅读全文 posted @ 2014-12-29 23:15 Liam Wang 阅读(9730)

全网最全ASP.NET MVC 教程汇总

全网最全ASP.NET MVC 教程汇总 MVC架构已深得人心,微软也不甘落后,推出了Asp.net MVC.小编特意整理博客园乃至整个网络最具价值的MVC技术原创文章,为想要学习ASP.NET MVC技术的学习者提供一个整合学习入口.本文从Why,What,How三个角度整理MVC 的学习资源,让学习者第一时间找到最有价值的文章,获取最彻底的ASp.NET MVC 框架知识,Let’s go! 1. Why :为什么需要ASP.NET MVC 本章主要为大家汇总了为什么学习Asp.net MV