ASP.NET MVC中异常Exception拦截的深入理解

由于客户端的环境不一致,有可能会造成我们预计不到的异常错误,所以在项目中,友好的异常信息提示,是非常重要的。在asp.net mvc中实现异常属性拦截也非常简单,只需要继承另一个类(System.Web.Mvc.FilterAttribute)和一个接口(System.Web.Mvc.IExceptionFilter),实现接口里面OnException方法,或者直接继承Mvc 提供的类System.Web.Mvc.HandleErrorAttribute。

下面话不多说了,来一起看看详细的介绍吧

二、实现关键逻辑

继承System.Web.Mvc.HandleErrorAttribute,重写了OnException方法,主要实现逻辑代码如下:

public class HandlerErrorAttribute : HandleErrorAttribute { /// <summary> /// 控制器方法中出现异常,会调用该方法捕获异常 /// </summary> /// <param>提供使用</param> public override void OnException(ExceptionContext context) { WriteLog(context); base.OnException(context); context.ExceptionHandled = true; if (context.Exception is UserFriendlyException) { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.OK; context.Result = new ContentResult { Content = new AjaxResult { type = ResultType.error, message = context.Exception.Message }.ToJson() }; } else if (context.Exception is NoAuthorizeException) { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized; if (!context.HttpContext.Request.IsAjaxRequest()) { context.HttpContext.Response.RedirectToRoute("Default", new { controller = "Error", action = "Error401", errorUrl = context.HttpContext.Request.RawUrl }); } else { context.Result = new ContentResult { Content = context.HttpContext.Request.RawUrl }; } } else { context.HttpContext.Response.StatusCode = (int)HttpStatusCode.InternalServerError; ExceptionMessage error = new ExceptionMessage(context.Exception); var s = error.ToJson(); if (!context.HttpContext.Request.IsAjaxRequest()) { context.HttpContext.Response.RedirectToRoute("Default", new { controller = "Error", action = "Error500", data = WebHelper.UrlEncode(s) }); } else { context.Result = new ContentResult { Content = WebHelper.UrlEncode(s) }; } } } /// <summary> /// 写入日志(log4net) /// </summary> /// <param>提供使用</param> private void WriteLog(ExceptionContext context) { if (context == null) return; if (context.Exception is NoAuthorizeException || context.Exception is UserFriendlyException) { //友好错误提示,未授权错误提示,记录警告日志 LogHelper.Warn(context.Exception.Message); } else { //异常错误, LogHelper.Error(context.Exception); ////TODO :写入错误日志到数据库 } } }

MVC 过滤器全局注册异常拦截:

public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandlerErrorAttribute()); } }

我们看到,context.Exception 分为3种:UserFriendlyException,NoAuthorizeException 或 Exception;UserFriendlyException 是指友好异常,前端友好提示错误信息。NoAuthorizeException 为401未授权异常,当页面未被授权访问时,返回该异常,并携带有未授权的路径地址。其他异常统一返回500错误,并携带异常信息。

三、异常处理 

1.401 未授权错误

异常定义代码:

/// <summary> /// 没有被授权的异常 /// </summary> public class NoAuthorizeException : Exception { public NoAuthorizeException(string message) : base(message) { } }

抛出异常代码:

throw new NoAuthorizeException("未授权");

前端UI效果:

ASP.NET MVC中异常Exception拦截的深入理解

2.404 未找到页面错误

MVC的404异常处理,有几种方式,我们采用了在Global.asax全局请求函数中处理, 请查看以下代码

protected void Application_EndRequest() { if (Context.Response.StatusCode == 404) { bool isAjax = new HttpRequestWrapper(Context.Request).IsAjaxRequest(); if (isAjax) { Response.Clear(); Response.Write(Context.Request.RawUrl); } else { Response.RedirectToRoute("Default", new { controller = "Error", action = "Error404", errorUrl = Context.Request.RawUrl }); } } }

前端UI效果:

ASP.NET MVC中异常Exception拦截的深入理解

3.500服务器内部错误 

500异常错误抛出的异常信息对象定义:

/// <summary> /// 异常错误信息 /// </summary> [Serializable] public class ExceptionMessage { public ExceptionMessage() { } /// <summary> /// 构造函数 /// 默认显示异常页面 /// </summary> /// <param>异常对象</param> public ExceptionMessage(Exception ex) :this(ex, true) { } /// <summary> /// 构造函数 /// </summary> /// <param>异常对象</param> /// <param>是否显示异常页面</param> public ExceptionMessage(Exception ex, bool isShowException) { MsgType = ex.GetType().Name; Message = ex.InnerException != null ? ex.InnerException.Message : ex.Message; StackTrace = ex.StackTrace.Length > 300 ? ex.StackTrace.Substring(0, 300) : ex.StackTrace; Source = ex.Source; Time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); Assembly = ex.TargetSite.Module.Assembly.FullName; Method = ex.TargetSite.Name; ShowException = isShowException; var request = HttpContext.Current.Request; IP = Net.Ip; UserAgent = request.UserAgent; Path = request.Path; HttpMethod = request.HttpMethod; } /// <summary> /// 消息类型 /// </summary> public string MsgType { get; set; } /// <summary> /// 消息内容 /// </summary> public string Message { get; set; } /// <summary> /// 请求路径 /// </summary> public string Path { get; set; } /// <summary> /// 程序集名称 /// </summary> public string Assembly { get; set; } /// <summary> /// 异常参数 /// </summary> public string ActionArguments { get; set; } /// <summary> /// 请求类型 /// </summary> public string HttpMethod { get; set; } /// <summary> /// 异常堆栈 /// </summary> public string StackTrace { get; set; } /// <summary> /// 异常源 /// </summary> public string Source { get; set; } /// <summary> /// 服务器IP 端口 /// </summary> public string IP { get; set; } /// <summary> /// 客户端浏览器标识 /// </summary> public string UserAgent { get; set; } /// <summary> /// 是否显示异常界面 /// </summary> public bool ShowException { get; set; } /// <summary> /// 异常发生时间 /// </summary> public string Time { get; set; } /// <summary> /// 异常发生方法 /// </summary> public string Method { get; set; } }

抛出异常代码:

throw new Exception("出错了");

前端UI效果:

ASP.NET MVC中异常Exception拦截的深入理解

4. UserFriendlyException 友好异常

异常定义代码:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdssdj.html