上一篇我们完善了多层开发的效率问题,传送门:项目架构开发:展现层(下)
这次我们完成架构的异常处理功能,异常处理一般都与日志分不开的,因为分析及定位问题需要一些详细信息;
稍微正规一点的公司,都会分开发、测试及生产环境。在本地及测试环境出BUG了,问题很好解决
调试跟踪问题,三下五除二就搞完了;但是在生产环境出问题,基本上是不允许直连数据库调试的;
这时候如何没有足够的异常信息参考,那你就悲催了,你等着加班熬夜吧。
为了解决这个问题,所以异常信息的捕捉及记录就显得非常重要了,一个完善的系统,出问题后不可能要去调试才能知道具体原因的
1、解决展现层的异常
1.1 其实ASP.NET MVC已经支持全局异常的处理,就是这个:HandleErrorAttribute,这里我们只是简单介绍他的使用方法
详情可以看看这篇文章:http://shiyousan.com/post/635838881238204198,下面我们一步步来。
FilterConfig.cs,这是系统默认生成的
1 using System.Web; 2 using System.Web.Mvc; 3 4 namespace Presentation.MVC 5 { 6 public class FilterConfig 7 { 8 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 { 10 filters.Add(new HandleErrorAttribute()); 11 } 12 } 13 }
1.2 要在Web.config中开启customErrors,不然没有效果
1 <customErrors mode="On" defaultRedirect="~/Error/Index"> 2 </customErrors>
1.3 设置好后,系统发生异常后会自动跳转到默认的Error.cshtml界面
1 <div class="container"> 2 <h1 class="text-danger">错误。</h1> 3 <h2 class="text-danger">处理你的请求时出错。</h2> 4 5 @if (Model != null) 6 { 7 <p class="bg-danger text-danger"> 8 异常类型:@Model.Exception.GetType().Name 9 </p> 10 <p class="bg-danger text-danger"> 11 触发异常的控制器:@Model.ControllerName 12 </p> 13 <p class="bg-danger text-danger"> 14 触发异常的操作方法:@Model.ActionName 15 </p> 16 <p class="bg-danger text-danger"> 17 错误信息:@Model.Exception.Message 18 </p> 19 <p class="bg-info text-info"> 20 页面路径:~/Views/Shared/Error.cshtml 21 </p> 22 } 23 </div>
1.4 我们再Home/Index初始页触发一个异常试试看
1 public ActionResult Login() 2 { 3 string str = null; 4 str.GetType();//空引用 5 6 return View(); 7 }
可以看到已经跳转到默认错误显示页面了
但是这样是不够的,一般这个页面会美化,客户端用户会看到更加友好的提示信息
而且这里并没有异常堆栈,看不到异常的具体信息,这样定位问题就困难;
所以还需要加工一下,我们设计一个自定义的异常处理类
2、自定义异常处理
2.1 LjrExecptionAttribute.cs,很简单啊,就不解释了
1 using Infrastructure.Core; 2 using System.Web.Mvc; 3 4 namespace Presentation.MVC 5 { 6 public class LjrExecptionAttribute : HandleErrorAttribute 7 { 8 public override void OnException(ExceptionContext filterContext) 9 { 10 Logger.Error(filterContext.Exception.Message, filterContext.Exception); 11 12 base.OnException(filterContext); 13 } 14 } 15 }
2.2 然后FilterConfig.cs 要改一下
1 public class FilterConfig 2 { 3 public static void RegisterGlobalFilters(GlobalFilterCollection filters) 4 { 5 //filters.Add(new HandleErrorAttribute()); 6 filters.Add(new LjrExecptionAttribute()); 7 } 8 }
2.3 web.config也改一下,因为HandleErrorAttribute 处理不了HTTP404
1 <customErrors mode="On" defaultRedirect="~/Error/Index"> 2 <error redirect="~/Error/NotFound" statusCode="404" /> 3 </customErrors>
2.4 新建ErrorController.cs
1 public class ErrorController : Controller 2 { 3 public ActionResult Index() 4 { 5 return View(); 6 } 7 8 public ActionResult NotFound() 9 { 10 return View(); 11 } 12 }
2.5 NotFound.cshtml
1 @{ 2 Layout = null; 3 } 4 5 <div style=" margin:0px auto; width:500px; margin:20px;">