zoukankan      html  css  js  c++  java
  • 在MVC中处理异常的总结

    无论是桌面程序还是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. 所以需要在ViewsShared下面建立一个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(),2); //by default added
        filters.Add(new HandleErrorAttribute
        {
            ExceptionType = typeof(System.Data.DataException),
            View = "DatabaseError"
        },1);
    }

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

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

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

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

    5. 扩展HandleErrorAttribute

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

     1 public class CustomHandleErrorAttribute : HandleErrorAttribute
     2 {
     3     public override void OnException(ExceptionContext filterContext)
     4     {
     5         if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
     6         {
     7             return;
     8         }
     9         if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
    10         {
    11             return;
    12         }
    13         if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
    14         {
    15             return;
    16         }
    17         // if the request is AJAX return JSON else view.
    18         if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    19         {
    20             filterContext.Result = new JsonResult
    21             {
    22                 JsonRequestBehavior = JsonRequestBehavior.AllowGet,
    23                 Data = new
    24                 {
    25                     error = true,
    26                     message = filterContext.Exception.Message
    27                 }
    28             };
    29         }
    30         else
    31         {
    32             var controllerName = (string)filterContext.RouteData.Values["controller"];
    33             var actionName = (string)filterContext.RouteData.Values["action"];
    34             var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
    35             filterContext.Result = new ViewResult
    36             {
    37                 ViewName = View,
    38                 MasterName = Master,
    39                 ViewData = new ViewDataDictionary(model),
    40                 TempData = filterContext.Controller.TempData
    41             };
    42         }
    43         // log the error by using your own method
    44         LogError(filterContext.Exception.Message, filterContext.Exception);
    45         filterContext.ExceptionHandled = true;
    46         filterContext.HttpContext.Response.Clear();
    47         filterContext.HttpContext.Response.StatusCode = 500;
    48         filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
    49     }
    50 }
    View Code

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

  • 相关阅读:
    多数据源配置
    Oracle创建JOB
    2新建Data Adapter
    注解的CRUD;重点:多对一和一对多处理
    Mybatis分页+使用注解开发!
    继续mybatis配置resultMap;讲解日志部分
    Today has a day off.
    Mybatis其他配置!
    Mybatis优化配置!
    Mybatis的CRUD
  • 原文地址:https://www.cnblogs.com/JustRun1983/p/3558741.html
Copyright © 2011-2022 走看看