• ASP.NET MVC3 异常处理 学习笔记


    ASP.NET MVC3 异常处理

    在ASP.NET MVC中可以使用HandleError特性很容易的实现错误的处理。

    使用HandleError Attribute,并且在web.config中设置CustomErrors,当程序中有未处理的异常时,可以定向到一个友好的视图页面。

    首先,我们通过反编译HandleError中的OnException方法,看一看是如何实现的:
     
    public virtual void OnException(ExceptionContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        if (!filterContext.IsChildAction && (!filterContext.ExceptionHandled && filterContext.HttpContext.IsCustomErrorEnabled))
        {
            Exception innerException = filterContext.Exception;
            if ((new HttpException(null, innerException).GetHttpCode() == 500) && this.ExceptionType.IsInstanceOfType(innerException))
            {
                string controllerName = (string) filterContext.RouteData.Values["controller"];
                string actionName = (string) filterContext.RouteData.Values["action"];
                HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
                ViewResult result = new ViewResult {
                    ViewName = this.View,
                    MasterName = this.Master,
                    ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
                    TempData = filterContext.Controller.TempData
                };
                filterContext.Result = result;
                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.Clear();
                filterContext.HttpContext.Response.StatusCode = 500;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            }
        }

    } 

     从中我们可以看到,如果一个未被处理的异常没有标记为“Handled”并且启用了自定义错误处理,该错误会在此处被捕获处理。

    Web.config中设置CustomError

    CustomError定义自动处理异常的行为,如下所示:

     <customErrors mode="On" defaultRedirect="~/Error/Unknown">

          <error statusCode="404" redirect="~/Error/NotFound" />
        </customErrors>

    Mode的值可以是OffOnRemoteOnly,不同的值定义研发阶段或产品发布后的行为。

    Mode值的使用场景:

    • On:开启自定义错误处理。
    • Off:关闭自定义错误处理,当发生异常时,就会看到ASP.NET的黄页信息。
    • RemoteOnly:如果在服务器上运行程序(http://localhost),当发生异常时,不会看到自定义异常信息,如果通过其他机器访问该程序,会看到自定义异常信息。该选项常用于开发人员调试程序,如果出现异常,开发人员可以通过本地访问来查看异常详细信息,而远程访问的用户看到的是自定义的异常。

      

    注意:

        如果使用了HandleError特性,并且启用了CustomError,当有未处理的异常发生时,MVC在被执行的HttpRequest的上下文中查找”Error”视图(当前Controler对应的View文件夹中或Shared文件夹中),并呈现给用户。在这种情况下,CustomError”defaultRedirect””redirect”属性会失效。注意:如果找不到Error视图,会使用”defaultRedirect””redirect”的定向。

        如果没有使用HandleError,并且启用了CustomError,当有未处理的异常发生时,会重定向到”defaultRedirect””redirect”属性指定的url,如上例的/Error/

    Unknown

         提示:ASP.N.NET MVC3中,默认对所有的Controller注册全局HandleError,因此不用担心应用程序中的Controller没有使用HandleError。在之前版本中没有全局过滤器,HandleError必须对每个actioncontroller手工定义。

        在web.configCustomError中,也可以设置当异常出现重新定向到一个静态页面,如下:

     <customErrors mode="On" defaultRedirect="Custom404.htm">

        
        </customErrors>

        注意:静态页面需要放到web网站根目录下,否则无法定向到。

    异常处理时执行其他功能的方法:

    1、重写Controller的OnException方法

    如果我们不仅仅在出现异常时显示自定义的错误页面,需要记录错误日志,那么可以通过继承Controller类并重些OnException方法实现。如果我们MVC程序的所有Controller都需要记录日志,可以创建一个BaseController,重写OnExcetion方法,然后其他需要记录日志的Controller继承BaseController即可。例如:

      public class BaseController : Controller

      {

            protected override void OnException(ExceptionContext filterContext)

            {
                // 此处进行异常记录,可以记录到数据库或文本,也可以使用其他日志记录组件。
                // 通过filterContext.Exception来获取这个异常。
                string filePath = @"D:\Temp\Exceptions.txt";
                StreamWriter sw = System.IO.File.AppendText(filePath);
                sw.Write(filterContext.Exception.Message);
                sw.Close();
                // 执行基类中的OnException
                base.OnException(filterContext);

     }

    那么其他继承自BaseController的Controller就会实现记录错误日志的功能。

     

    2、创建FilterAttribute

    通过FilterAttribute,并把它添加到全局过滤器集合中就可以提供给整个应用程序使用,如果只需要在某几个Action中使用,可以在Controller的Action中添加此特性。

     

    Filter定义如下:

     public class LogExceptionFilterAttribute : FilterAttribute, IExceptionFilter

    {
        public void OnException(ExceptionContext filterContext)
        {
            // 添加记录日志代码
        }
    }

     

    如果要应用给所有的Controller的所有Action,在Global.asax.cs中实现下面代码即可:

     

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new LogExceptionFilterAttribute());
        filters.Add(new HandleErrorAttribute());
    }
      

    或者给只需要使用此特性的Controller或Action添加 :

     

    [LogExceptionFilter()]
    public ActionResult About()
    {
        throw new Exception("出错.");
    }
     

     参考文档:http://www.dotneat.net/2011/04/12/ErrorHandlingInASPNETMVC3.aspx

  • 相关阅读:
    好想再吻一次你的唇
    我会永远永远的爱你,直到你不爱我的那一天
    我会永远永远的爱你,直到你不爱我的那一天
    回到你身边
    回到你身边
    两只公蚊子的故事
    两只公蚊子的故事
    洛谷P1090: 合并果子
    洛谷 P1288 :取数游戏II
    洛谷P1164 :小A点菜
  • 原文地址:https://www.cnblogs.com/kinglau/p/2215362.html
Copyright © 2020-2023  润新知