我在Global.asax中尝试
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
this.Error += new EventHandler(MvcApplication_Error);
}
public void MvcApplication_Error(object sender, EventArgs e)
{
throw new NotImplementedException();
}
但事件从未被提出过!
答案 0 :(得分:8)
优雅处理未处理异常的最简单方法是(A)使用Elmah挂钩未处理的异常并记录它们,以及(B)使用global.asax的Application_Error()方法捕获未处理的异常。这是我的:
protected void Application_Error( object sender , EventArgs e )
{
// only do something special if the request is not from the local machine.
if ( !Request.IsLocal )
{
Exception exception = Server.GetLastError() ;
HttpException httpException = exception as HttpException ;
RouteData routeData = new RouteData() ;
routeData.Values.Add( "controller" , "Error" ) ;
if ( httpException != null )
{
int httpStatusCode = httpException.GetHttpCode() ;
switch ( httpStatusCode )
{
case 404 : routeData.Values.Add( "action" , "Http404FileNotFound" ) ; break ;
default : routeData.Values.Add( "action" , "HttpError" ) ; break ;
}
routeData.Values.Add( "exception" , httpException ) ;
}
else
{
routeData.Values.Add( "action" , "Http500InternalServerError" ) ;
routeData.Values.Add( "exception" , exception ) ;
}
Response.Clear() ;
Server.ClearError() ;
HttpContextBase contextWrapper = new HttpContextWrapper( Context ) ;
RequestContext newContext = new RequestContext( contextWrapper , routeData ) ;
IController errorController = new ErrorController() ;
errorController.Execute( newContext ) ;
}
return ;
}
以上方法:
对于本地请求(例如,开发人员的机器),不处理异常并且ASP.Net回退标准黄屏O'Death。
通过显示(不重定向 - 用户看到原始URL)处理远程请求,这是一个友好的错误页面,不会泄漏实现信息(如堆栈跟踪等)。逻辑如下:
如果异常可以转换为HttpException,则会检查HTTP状态(响应)代码。 Http状态代码404显示我们的“未找到资源”视图,具有404响应状态;其他HttpExceptions获得一个不同的“Http Error”视图,将响应状态设置为500(内部服务器错误)。
如果无法将异常强制转换为HttpException,则会返回“内部错误”视图,该视图还会将响应状态设置为500(内部服务器错误)。
轻松!您可能希望在适当的地方使用log4net(例如,在抛出异常时)记录可能有助于调试异常根本原因的任何上下文数据。
答案 1 :(得分:7)
您可以使用Controller MetaData中已有的OnException方法
protected override void OnException(ExceptionContext filterContext)
{
//Build of error source.
string askerUrl = filterContext.RequestContext.HttpContext.Request.RawUrl;
Exception exToLog = filterContext.Exception;
exToLog.Source = string.Format("Source : {0} {1}Requested Path : {2} {1}", exToLog.Source, Environment.NewLine, askerUrl);
//Log the error
ExceptionLogger.Publish(exToLog, "unhandled", filterContext.RequestContext.HttpContext.Request.ServerVariables.ToString(), askerUrl);
//Redirect to error page : you must feed filterContext.Result to cancel already executing Action
filterContext.ExceptionHandled = true;
filterContext.Result = new ErrorController().ManageError(ErrorResources.GeneralErrorPageTitle, ErrorResources.GeneralErrorTitle, ErrorResources.GeneralErrorInnerBody, exToLog);
base.OnException(filterContext);
}
答案 2 :(得分:2)
除了Nico的建议,您还可以使用控制器上的属性,例如......
[ExceptionHandler("DefaultError", typeof(DivideByZeroException))]
public class HomeController : N2Controller
{
[ControllerAction, ExceptionHandler("Error")]
public void Index()
{
}
}
这允许您在需要时对异常处理程序进行更细粒度的控制(每个方法),或者在基本控制器中只有一个属性来处理所有错误。
答案 3 :(得分:0)
为了使其工作,您必须在MvcApplication构造函数中注册事件:
public MvcApplication()
{
Error += MvcApplication_Error;
}
private void MvcApplication_Error(object sender, EventArgs e)
{
//Do your stuff
}