ASP.NET MVC中错误处理方式

aspnet mvc的错误处理方式主要有以下两种

方式一:通过对controller或者action标记HandleError属性,然后指定一个错误页即可。这种方式最简单,不需要额外增加action ,仅仅需要增加错误页,但是不能记录日志(因为没有action,其实在aspx中也可调用记录日志的方法)。这个错误页还可以定义为强类型,类型为HandleErrorInfo,具体的Model又框架传递,可获取具体的异常信息。

 

ExpandedBlockStart.gif HandlError
///   <summary>
        
///  标记了HandleError,并指明错误处理页为AboutError.aspx
        
///   </summary>
        
///   <returns></returns>
        [HandleError(View  =   " AboutError " )]
        
public  ActionResult About()
        {
            
return  View();
        }
ExpandedBlockStart.gif AboutError.aspx
<% @ Page Title = ""  Language = " C# "  MasterPageFile = " ~/Views/Shared/Site.Master "  Inherits = " System.Web.Mvc.ViewPage<HandleErrorInfo> "   %>

< asp:Content ID = " Content1 "  ContentPlaceHolderID = " TitleContent "  runat = " server " >
    AboutError
</ asp:Content >

< asp:Content ID = " Content2 "  ContentPlaceHolderID = " MainContent "  runat = " server " >
    通过强类型获取异常信息
    
<%=  Model.Exception.Message  %>
</ asp:Content >

这种方式比较灵活,比如需要对某个action定义个错误页,就可采用这种方式。不过会有个小问题,后面会提到。

 

方式二:重写controller类的onException方式,这种方式最直接了,通常用于一个项目的BaseController中,那么以后的controller都继承这个类即可,可以在cs代码中记录错误日志,但是要定义错误页的action和具体的错误页面。方法中需要设置ExceptionHandled=true,否则错误会被抛到外层,这时候只能通过传统的aspnet错误方式处理了,通常是招CustomerError中配置的错误页,如果没有配置,那就出现一个大黄页了。ExceptionHandled=true这个操作会是逻辑有微妙的变化,后续提到。

ExpandedBlockStart.gif 重写OnException
  protected   override   void  OnException(ExceptionContext filterContext)
        {
            
//  标记异常已处理
            filterContext.ExceptionHandled  =   true ;
            
//  跳转到错误页
            filterContext.Result  =   new  RedirectResult(Url.Action( " Error " " Shared " ));
        }

 

  讲了这两种方式,主要是为了讲这两种方式混用时会出现的问题。如果以action标记了HandleError属性,同时期所在的controller又重写了OnException方法,最终会怎样处理呢?按照mvc中filter的执行顺序,controller重写的方法会被优先执行,不考虑action中的order顺序,执行完毕之后再执行action标记的filter的方法。ok,有了这个理论之后,再看看之前提到的情况的执行顺序。首先执行OnException中的处理方式,这时候filterContext.ExceptionHandled已经被标记为true了,再执行HandleError属性的方法时,就不会在被执行了,也就是说自定义的错误页白费了,不起作用。这是因为内置的HandleError在执行的时候会先判断filterContext.ExceptionHandled是否为true,为true就不执行了,因此会出现一些很奇怪的bug,明白这个道理就知道如何处理了。

       但是总不能把filterContext.ExceptionHandled = true;这行代码去掉,因为其他action没有标记handle error属性,如果不使filterContext.ExceptionHandled为true, 那么错误还是会抛到外层,又交给CustomerError处理了,还是白搭。因此既要保持基类的OnException方法,又要有action自己个性化的错误页,是不能使用系统内置的方式处理,只能自己再去定义ExceptionFilter 了,就是方式三。

 方式三,自定义ExceptionFilter,需要继承FilterAttribute,和实现IExceptionFilter接口,实现中不需要判断Exception是否已处理,但要注意需要有AboutError这个action。

 

ExpandedBlockStart.gif 自定义ExceptionFilter
     public   class  AboutErrorAttribute : FilterAttribute, IExceptionFilter
    {
        
#region  IExceptionFilter 成员

        
public   void  OnException(ExceptionContext filterContext)
        {
            UrlHelper url 
=   new  UrlHelper(filterContext.RequestContext);
            filterContext.Result 
=   new  RedirectResult(url.Action( " AboutError " " AboutError " ));
        }

        
#endregion
    }

 

那么action中需要改成

ExpandedBlockStart.gif View Code
         ///   <summary>
        
///  标记自定义的AboutError
        
///   </summary>
        
///   <returns></returns>
        [AboutError]
        
public  ActionResult About()
        {
            
return  View();
        }

 

经过一轮折腾,总算实现了需求,即保证了通用异常被正常处理,个别action个性化的错误页面也能实现,还算比较整洁。但最好框架的HandleError能够提供是否忽略判断异常是否已被处理过的属性设置。

转载于:https://www.cnblogs.com/shenba/archive/2011/04/16/2018441.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值