ASP.NET MVC中的统一化自定义异常处理
使用系统默认的错误处理方式,可以减少一次重定向访问,并且正常提示了错误信息,并发送了错误码500,但应注意以下问题:
一、需要修改web.config
<customErrors mode="On">
</customErrors>
二、如果修改默认的Error.cshtml文件,不使用默认布局页或修改布局页,应引用下列文件
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
三、默认的HandleErrorAttribute只处理500错误,所以应重写此类并加入过滤器。写入日志。
HandleErrorAttribute源码(可能与最新源码不一致)
public virtual void OnException(ExceptionContext filterContext){if (filterContext == null){throw new ArgumentNullException("filterContext");}if (filterContext.IsChildAction){return;}// If custom errors are disabled, we need to let the normal ASP.NET exception handler// execute so that the user can see useful debugging information.if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled){return;}Exception exception = filterContext.Exception;// If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),// ignore it.if (new HttpException(null, exception).GetHttpCode() != 500){return;}if (!ExceptionType.IsInstanceOfType(exception)){return;}string controllerName = (string)filterContext.RouteData.Values["controller"];string actionName = (string)filterContext.RouteData.Values["action"];HandleErrorInfo model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);filterContext.Result = new ViewResult{ViewName = View,MasterName = Master,ViewData = new ViewDataDictionary<HandleErrorInfo>(model),TempData = filterContext.Controller.TempData};filterContext.ExceptionHandled = true;filterContext.HttpContext.Response.Clear();filterContext.HttpContext.Response.StatusCode = 500;// Certain versions of IIS will sometimes use their own error page when// they detect a server error. Setting this property indicates that we// want it to try to render ASP.NET MVC's error page instead.filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;}
如果不使用过滤器,参考下面内容
===========================================================================================================================================
使用HandleErrorAttribute后,找到了Error.cshtml,则此时异常已经被捕获处理,所以不会再次被Application_Error捕获处理。
所以啊,如果想使用Application_Error,就要
public class FilterConfig{public static void RegisterGlobalFilters(GlobalFilterCollection filters){//filters.Add(new HandleErrorAttribute()); }}
=======================================================================================================================================================================================
当ASP.NET MVC程序出现了异常,怎么处理更加规范?
1. 最简单的方法是设置<customErrors/>节点
<customErrors>节点用于定义一些自定义错误信息的信息。此节点有Mode和defaultRedirect两个属性,其中defaultRedirect属性是一个可选属性,表示应用程序发生错误时重定向到的默认URL,如果没有指定该属性则显示一般性错误。Mode属性是一个必选属性,它有三个可能值,它们所代表的意义分别如下: On 表示在本地和远程用户都会看到自定义错误信息。 Off 禁用自定义错误信息,本地和远程用户都会看到详细的错误信息。 RemoteOnly 表示本地用户将看到详细错误信息,而远程用户将会看到自定义错误信息。
这里有必要说明一下本地用户和远程用户的概念。当我们访问asp.net应用程时所使用的机器和发布asp.net应用程序所使用的机器为同一台机器时成为本地用户,反之则称之为远程用户。在开发调试阶段为了便于查找错误Mode属性建议设置为Off,而在部署阶段应将Mode属性设置为On或者RemoteOnly,以避免这些详细的错误信息暴露了程序代码细节从而引来黑客的入侵。
<error>子节点
在<customErrors>节点下还包含有<error>子节点,这个节点主要是根据服务器的HTTP错误状态代码而重定向到我们自定义的错误页面,注意要使<error>子节点下的配置生效,必须将<customErrors>节点节点的Mode属性设置为“On”。下面是一个例子:
- <customErrors mode="On" defaultRedirect="GenericErrorPage.htm">
- <error statusCode="403" redirect="403.htm" />
- <error statusCode="404" redirect="404.htm" />
- </customErrors>
<customErrors mode="On" defaultRedirect="GenericErrorPage.htm"> <error statusCode="403" redirect="403.htm" /> <error statusCode="404" redirect="404.htm" />
</customErrors>
在上面的配置中如果用户访问的页面不存在就会跳转到404.htm页面,如果用户没有权限访问请求的页面则会跳转到403.htm页面,403.htm和404.htm页面都是我们自己添加的页面,我们可以在页面中给出友好的错误提示。
2. 使用过滤器HandleErrorAttribute
随着ASP.NET MVC版本的更新,出现了HandleErrorAttribute,使用Filter以AOP的思想实现了针对于Action的异常处理。使用此Filter后,当程序中出现异常的时候,会去封装这些异常信息,然后路由自动转到该Controller对应的Error.cshtml中,如果此路径下没有改文件,则会到shared目录中寻找此文件。另外一个相关的是在Global.asax中的protected void Application_Error(object sender, EventArgs e)方法,是捕捉异常的最后一道防线,也就是说,这是最高层次的异常捕获处理逻辑。使用HandleErrorAttribute后,找到了Error.cshtml,则此时异常已经被捕获处理,所以不会再次被Application_Error捕获处理。此外,可以通过@model HandleErrorInfo 在Error.cshtml中定制显示异常信息。有一点需要注意的是,HandleErrorAttribute是在customErrors基础之上的,如果想使用HandleErrorAttribute,customErrors的Mode必须要设置为On或RemoteOnly. 否则,HandleErrorAttribute将不起作用。
3. 自定义显示路径
如果遇到异常后不单单是要自定义异常显示,而且还需要进行日志记录。此时,可以通过继承扩展HandleErrorAttribute来实现新的Filter,然后在lobal.ascx中对所有的Action进行注册,filters.Add(new MyHandleErrorAttribute()).在这里详细说明一下另一种方式。我们可以写一个专门的Controller和Action来进行异常发生时的路由设置.
- public class UtilityController : Controller
- {
- public ActionResult Error()
- {
- return View();
- }
- public ActionResult PageNotFound()
- {
- return View();
- }
- }
public class UtilityController : Controller{public ActionResult Error(){return View();}public ActionResult PageNotFound(){return View();}
}
当出现异常的时候,把异常抛到最顶端,由Application_Error统一处理。这里的统一处理就包括,记录日志,重新进行页面定向等。
- {
- var ex = Server.GetLastError();
- Log.Error(ex); //记录日志信息
- var httpStatusCode = (ex is HttpException) ? (ex as HttpException).GetHttpCode() : 500; //这里仅仅区分两种错误
- var httpContext = ((MvcApplication)sender).Context;
- httpContext.ClearError();
- httpContext.Response.Clear();
- httpContext.Response.StatusCode = httpStatusCode;
- var shouldHandleException = true;
- HandleErrorInfo errorModel;
- var routeData = new RouteData();
- routeData.Values["controller"] = "Utility";
- switch (httpStatusCode)
- {
- case 404:
- routeData.Values["action"] = "PageNotFound";
- errorModel = new HandleErrorInfo(new Exception(string.Format("No page Found", httpContext.Request.UrlReferrer), ex), "Utility", "PageNotFound");
- break;
- default:
- routeData.Values["action"] = "Error";
- Exception exceptionToReplace = null; //这里使用了EntLib的异常处理模块的一些功能
- shouldHandleException = ExceptionPolicy.HandleException(ex, "LogAndReplace", out exceptionToReplace);
- errorModel = new HandleErrorInfo(exceptionToReplace, "Utility", "Error");
- break;
- }
- if (shouldHandleException)
- {
- var controller = new UtilityController();
- controller.ViewData.Model = errorModel; //通过代码路由到指定的路径
- ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
- }
- }
- }
转载于:https://www.cnblogs.com/dotnetmvc/p/3658456.html
ASP.NET MVC中的统一化自定义异常处理相关推荐
- asp.net MVC 中 Session统一验证的方法
验证登录状态的方法有:1 进程外Session 2 方法过滤器(建一个类继承ActionFilterAttribute)然后给需要验证的方法或控制器加特性标签 3 :新建一个BaseContro ...
- ASP.NET MVC中的身份验证
传统的登录验证方式,是通过将用户的登录状态信息保存在服务端的Session中,再利用客户端浏览器的Cookie保存SessionID,这样浏览器每次在向服务端发起请求时,都会携带该Cookie值,服务 ...
- ASP.NET MVC中你必须知道的13个扩展点
ScottGu在其最新的博文中推荐了Simone Chiaretta的文章13 ASP.NET MVC extensibility points you have to know,该文章为我 ...
- 在Asp.Net MVC中使用ModelBinding构造Array、List、Collection以及Dictionary
在asp.net mvc中,我们可以在html表单中使用特定的格式传递参数,从而通过model binder构造一些集合类型. 第一种方式 public ActionResult Infancy(Pe ...
- asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证
asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型的绑定和验证 原文:asp.net mvc源码分析-DefaultModelBinder 自定义的普通数据类型 ...
- 如何在 ASP.NET MVC 中集成 AngularJS
介绍 当涉及到计算机软件的开发时,我想运用所有的最新技术.例如,前端使用最新的 JavaScript 技术,服务器端使用最新的基于 REST 的 Web API 服务.另外,还有最新的数据库技术.最新 ...
- 通过源代码研究ASP.NET MVC中的Controller和View(三)
通过源代码研究ASP.NET MVC中的Controller和View(一) 通过源代码研究ASP.NET MVC中的Controller和View(二) 第三篇来了,上一篇我已经把VirtualPa ...
- 【转载】ASP.NET MVC中Controller与View之间的数据传递总结
在ASP.NET MVC中,经常会在Controller与View之间传递数据,因此,熟练.灵活的掌握这两层之间的数据传递方法就非常重要.本文从两个方面进行探讨: Ø Controller向View传 ...
- Asp.Net MVC中身份认证和授权
MVC自带的ActionFilter 在Asp.Net WebForm的中要做到身份认证微软为我们提供了三种方式,其中最常用的就是我们的Form认证,需要配置相应的信息.例如下面的配置信息: < ...
最新文章
- PAT 乙级 1041 考试座位号
- Asp.net服务器端控件CheckBoxList的使用心得
- python数据库查询怎么用变量_python中带变量的SQL查询
- 【Nutch2.2.1基础教程之6】Nutch2.2.1抓取流程
- c#事件的发布-订阅模型_微信灰度测试订阅号付费功能,小米推出最便宜5G套餐,腾讯辟谣高管猝死赔钱事件,核心期刊发布十岁儿童文章,这就是今天的其他大新闻!...
- php网站开发项目实战,PHP动态网站开发项目实战
- spring 集成mybatis——多数据源切换(附带定时器的配置)
- windows安装vnm
- WPF--常用布局介绍
- 这几道Redis面试题都不懂,怎么拿到阿里后端offer?
- 中国现代文学专题形考2022
- wincc远程服务器配置,WINCC-OPC服务器配置
- ConstraintLayout 属性详解 和Chain的使用
- 适配iPhone XR/iPhone XS Max
- java合成tif图片_C# 将图片合成tif文件
- H5 左右滑屏切页原理
- Spring事务抛出Exception异常不回滚
- python3 asyncio原理_Python3 asyncio Lock 协程锁实现原理
- unity3d之读取图集图片
- 如何kill掉Ubuntu的僵死进程
热门文章
- 学习dubbo遇到的问题1
- dubbo简易实现_分别利用自定义的注册中心和zookeeper
- 计算机面试书籍与求职网站推荐
- Namenode双机热备之Pacemaker
- 【译】TetroGL: An OpenGL Game Tutorial in C++ for Win32 Platforms - Part 2 (上)
- RabbitMq入门(七)消息处理(消息持久化autoDelete、消息确认ACK机制)
- 统计一个长度为2的子字符串在另一个字符串中出现的次数.例如:假定输入的字符串为“asd asasdfg asd as zx67 asd mklo”,子字符串为“as”,函数返回值为6。
- Linux-0.11内核学习-添加系统调用
- 用事件驱动编程解救臃肿的代码
- GC:垃圾回收机制及算法