无论是桌面程序还是web程序,异常处理都是必须的. 一般的处理方式是, 捕获异常,然后记录异常的详细信息到文本文件或者数据库中.
在Asp.net MVC中可以使用内建的filter——HandleError来处理程序发生的异常。接下来,来看看如何在我们的MVC项目中使用。

要让HandleErrorAttribute特性工作,需要修改我们的Web.config文件配置

</system.web>
...
<customErrors mode="On" defaultRedirect="Error.htm"/>
</system.web>

HandleErrorAttribute 特性能够在Action, Controller, 和Global 三个级别中使用

1. 在 Action方法级别使用

在Action方法上使用,非常简单,只需要在方法头上加上HandleError特性,告诉MVC如果该Action方法出现异常,交由HandleError特性处理

[HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")]
public ActionResult Index(int id)
{
var db = new MyDataContext();
return View("Index", db.Categories.Single(x => x.Id == id));
}

上面例子中,当在运行Index方法的时候,如果发生数据库异常,  MVC 将会显示DatabaseError view. 所以需要在Views\Shared\下面建立一个DatabaseError.cshtml。

2. 在 Controller级别使用

同Action相似,只需要简单的将改特性放到controller类头上,告诉MVC如果该Controller中的Action方法出现异常,都交由HandleError特性处理

[HandleError(ExceptionType = typeof(System.Data.DataException), View = "DatabaseError")]
public class HomeController : Controller
{
/* Controller Actions with HandleError applied to them */
}

3. 在Global级别上使用

我们也可以把HandleError特性注册到全局级别,使得它在全局范围中起作用。全局范围起作用的意思是,项目中的所有controller都使用HandleError处理异常。要注册global级别, 在项目的文件夹App_Start中打开 FilterConfig.cs文件找到RegisterGlobalFilters方法

默认的, ASP.NET MVC已经把HandleError特性注册成global. 这里你可以添加自定义的filter

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute
{
ExceptionType = typeof(System.Data.DataException),
View = "DatabaseError"
});
filters.Add(new HandleErrorAttribute()); //by default added
}

一定要注意, 全局的filter是依照它们注册的顺序执行的。所以如果有多个filter, 要在注册其它fileter之前注册error filter

当然,你也可以在注册global filter的时候,指定它们的顺序。下面的代码是指定了顺序的,和上面的等价。

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new HandleErrorAttribute(),); //by default added
filters.Add(new HandleErrorAttribute
{
ExceptionType = typeof(System.Data.DataException),
View = "DatabaseError"
},);
}

4. 使用MVC默认的HandleError特性的局限性

  1. 没有办法记录错误日志

  2. 它只捕获http 500错误, 但是不捕获其它类型的Http错误,比如404, 401等。

  3. 如果是在Ajax请求的情况下,返回的错误view,对于ajax访问没有任何意义。如果在Ajax请求出错的情况下,返回json对于客户端的处理就容易和友好的多。

5. 扩展HandleErrorAttribute

我们可以通过继承 HandleError filter来实现自己的异常处理filter.  下面的filter, 实现了在出现错误的时候,记录异常日志和在Ajax请求异常的情况下,返回json对象.

 public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
{
return;
}
if (new HttpException(null, filterContext.Exception).GetHttpCode() != )
{
return;
}
if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
{
return;
}
// if the request is AJAX return JSON else view.
if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
filterContext.Result = new JsonResult
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
error = true,
message = filterContext.Exception.Message
}
};
}
else
{
var controllerName = (string)filterContext.RouteData.Values["controller"];
var actionName = (string)filterContext.RouteData.Values["action"];
var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
filterContext.Result = new ViewResult
{
ViewName = View,
MasterName = Master,
ViewData = new ViewDataDictionary(model),
TempData = filterContext.Controller.TempData
};
}
// log the error by using your own method
LogError(filterContext.Exception.Message, filterContext.Exception);
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = ;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
}
}

以上就是在MVC开发中,自己常用到的一些小技巧,希望对大家有帮助。

在MVC中处理异常的总结的更多相关文章

  1. spring MVC中的异常统一处理

    1.spring MVC中定义了一个标准的异常处理类SimpleMappingExceptionResolver 该类实现了接口HandlerExceptionResolver 2.看下SimpleM ...

  2. spring MVC中定义异常页面

    如果我们在使用Spring MVC的过程中,想自定义异常页面的话,我们可以使用DispatcherServlet来指定异常页面,具体的做法很简单: 下面看我曾经的一个项目的spring配置文件: 1 ...

  3. 在MVC中添加异常增加日志

    MVC的结构非常棒,基本你能想到注入的地方都可以找到地方,譬如IActionFilter,IResultFilter,IAuthorizationFilter以及IExceptionFilter 以下 ...

  4. MVC与WebApi中的异常过滤器

    一.MVC的异常过滤器   1.自定义MVC异常过滤器 创建一个类,继承HandleErrorAttribute即可,如果不需要作为特性使用直接实现IExceptionFilter接口即可, 注意,该 ...

  5. 解决MVC中JSON字符长度超出限制的异常

    解决MVC中JSON字符长度超出限制的异常 解决方法如下: <configuration> <system.web.extensions> <scripting> ...

  6. MVC中使用过滤器记录异常日志

    using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace Filte ...

  7. ASP.NET MVC中注册Global.asax的Application_Error事件处理全局异常

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

  8. 在ASP.NET MVC中使用Log4Net记录异常日志,出错时导向到静态页

    本篇体验在ASP.NET MVC 4中使用Log4Net记录日志. 通过NuGet安装Log4Net. 需求是:当出错时导向到Error.html静态页面,Log4Net记录错误信息. 大致的思路是: ...

  9. 获取MVC中Controller下的Action参数异常

    我现在做的一个项目有一个这样的需求, 比如有一个页面需要一个Guid类型的参数: public ActionResult Index(Guid id) { //doing something ... ...

随机推荐

  1. 关于VS项目平台的x86,x64,Any CPU以及Debug和Release的区别

    相信对于很多刚接触打包程序的同志来说,关于x86,x64,Any CPU这三个项目平台,以及解决方案配置Debug和Release有什么区别?这个问题一定有许多的困惑,甚至不乏一些已经工作了很久的老程 ...

  2. Android使用SQLite数据库(2)

    打开SQLite数据库,首先要建立一个DatabaseHelper类的实例,然后,再获得数据库: DatabaseHelper mDBH; SQLiteDatabase db; mDBH = new ...

  3. 第 15 章 CSS 文本样式[上]

    学习要点: 1.字体总汇 2.字体设置 3.Web 字体 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 文本样式,通过文本样式的设置,更改字体的大小.样式以及文本的方位. 一.字体总汇 本节 ...

  4. Bootstrap Table表格一直加载(load)不了数据-解决办法

    bootstrap-table是一个基于Bootstrap风格的强大的表格插件神器,官网:http://bootstrap-table.wenzhixin.net.cn/zh-cn/ 这里列出遇到的一 ...

  5. 回文字算法(java版本)

    package com.gdh.backtext;import java.util.HashMap;import java.util.Map;import java.util.Map.Entry; p ...

  6. Verilog学习笔记基本语法篇(十三)...............Gate门

    Verilog中已有一些建立好的逻辑门和开关的模型.在所涉及的模块中,可通过实例引用这些门与开关模型,从而对模块进行结构化的描述. 逻辑门: and (output,input,...) nand ( ...

  7. Eclipse安装SVN插件及使用说明

    1.下载Eclipse,如果没有安装的请到这里下载安装:http://eclipse.org/downloads/ ,关于Eclipse的下载安装不再赘述. 2.下载SVN插件subclipse,安装 ...

  8. 那些年,我们一起疯狂的C#

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  9. Java基础学习 -- Java(OOP)程序的设计原则

    避免代码复制.解决方案:函数.父类: 封装.尽量private每个类的成员变量,用操作封装数据,减少类与类之间成员变量的直接调用,而是调用method,降低耦合: 可扩展性最大化.尽量使用框架+数据的 ...

  10. css知多少(10)——display

    1. 引言 网页的所有元素,除了“块”就是“流”,而且“流”都是包含在“块”里面的(最外层的body就是一个“块”).在本系列一开始讲<浏览器默认样式>的时候,大家也都看到了浏览器默认样式 ...