代码改变世界

[整理]ASP.NET 中异常处理

2015-01-06 16:58  Benoly  阅读(298)  评论(0)    收藏  举报

[整理]ASP.NET 中异常处理

1.直接通过重写Controller的OnException来处理异常#

public class HomeController : Controller
{
public ActionResult Index( )
{
throw new Exception( "test ex." );
return View( );
}

protected ILog Log
{
get { return LogManager.CreateLog( ); }
}

protected override void OnException( ExceptionContext filterContext )
{
// 处理异常
if( !filterContext.ExceptionHandled )
{
var ex = filterContext.Exception;
Log.Error( ex.Message );
Log.Error( ex.StackTrace );

filterContext.ExceptionHandled = true;
}

base.OnException( filterContext );
}
}

2.通过添加自定义Filter并继承HandleErrorAttribute,重写OnException来处理异常

public class MvcHandleErrorAttribute : HandleErrorAttribute
{
protected ILog Log
{
get { return LogManager.CreateLog( ); }
}

public override void OnException( ExceptionContext filterContext )
{
// 处理异常
if( !filterContext.ExceptionHandled )
{
var ex = filterContext.Exception;
Log.Error( ex.Message );
Log.Error( ex.StackTrace );

filterContext.ExceptionHandled = true;
}

base.OnException( filterContext );
}
}

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

方案1和2可以单独使用,也可以同时使用,但是要注意的是,如果方案1和2同时存在,先进入方案2的OnException,后进入方案1的OnException,所以为了避免重复处理,在处理完异常后,执行
filterContext.ExceptionHandled = true;
这样,服务端响应返回一个EmptyResult实例,而不再返回一个异常(常见的黄页)

方案2中,由于自定义Filter是特性Attribute,即可以设置全局,也可以设置Controller,也可以设置Action,

3.通过自定义IHttpModule或是Global里处理异常

public class ExceptionModule : IHttpModule
{
private HttpApplication _application;

protected ILog Log
{
get { return LogManager.CreateLog( ); }
}

public void Dispose( )
{
//DO NOTHING
}

public void Init( HttpApplication context )
{
_application = context;

//注册异常事件方法
_application.Error += new EventHandler( OnApplicationError );
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( CurrentDomain_UnhandledException );
}

void OnApplicationError( object sender, EventArgs e )
{
var loggedAccout = WebWorkContext.Current.LoggedAccount;
var ex = _application.Server.GetLastError( );

Log.Error( ( loggedAccout == null ) ? "n/a" : loggedAccout.Name );
Log.Error( ex.Message );
Log.Error( ex.StackTrace );
}

void CurrentDomain_UnhandledException( object sender, UnhandledExceptionEventArgs e )
{
if( e.ExceptionObject == null )
return;

Exception ex = e.ExceptionObject as Exception;
Log.Error( ex.Message );
Log.Error( ex.StackTrace );
}
}

和自定义IHttpModule里一样,在Global的 Application_Start里注册异常事件方法
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start( )
{
//注册异常事件方法
this.Error += new EventHandler( OnApplicationError );
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( CurrentDomain_UnhandledException );
}

void OnApplicationError ( object sender, EventArgs e )
{
var ex = _application.Server.GetLastError( );
Log.Error( ex.Message );
Log.Error( ex.StackTrace );
}
}

4.未解决的问题

public class HomeController :Controller
{
public ActionResult Index( )
{
int count = 0;

Thread thread = new Thread( ( ) =>
{
throw new Exception( "Test线程异常" );//异常无限循环抛出,WebDev.Server4.0.exe停止工作。如何解决?
} );

thread.Start( );

//throw new Exception( "test ex." );

return View( );
}
}

5.WebApi中

public class WebApiExceptionFilterAttribute : ExceptionFilterAttribute
{
protected ILog Log
{
get { return LogManager.CreateLog( ); }
}

public override void OnException( HttpActionExecutedContext actionExecutedContext )
{
//处理异常
var ex = actionExecutedContext.Exception;
Log.Error( ex.Message );
Log.Error( ex.StackTrace );

base.OnException( actionExecutedContext );
}
}

public static class WebApiConfig
{
public static void Register( HttpConfiguration config )
{
...
config.Filters.Add( new WebApiExceptionFilterAttribute( ) );
}
}

参考:

http://www.cnblogs.com/luminji/archive/2011/01/05/1926033.html
http://www.asp.net/web-api/overview/error-handling/exception-handling