ASP.NET MVC的HandleError

我如何去在asp.net MVC预览5中的[HandleError]filter?
我在我的Web.config文件中设置了customErrors

 <customErrors mode="On" defaultRedirect="Error.aspx"> <error statusCode="403" redirect="NoAccess.htm"/> <error statusCode="404" redirect="FileNotFound.htm"/> </customErrors> 

并把[HandleError]放在我的控制器类上面,如下所示:

 [HandleError] public class DSWebsiteController: Controller { [snip] public ActionResult CrashTest() { throw new Exception("Oh Noes!"); } } 

然后我让我的控制器从这个类inheritance,并调用CrashTest()。 Visual Studio暂停在错误,并按f5继续后,我重新路由到Error.aspx?aspxerrorpath = / sxi.mvc / CrashTest(其中sxi是所用的控制器的名称。当然path无法find,我得到“/'应用程序中的服务器错误”404。

这个网站已经从预览版3移植到了5.除了error handling以外,所有的东西都运行(并没有太多的工作来移植)。 当我创build一个完整的新项目,error handling似乎工作。

想法?

– 注意 –
由于这个问题现在有超过3K的意见,我认为这是有利的,把我目前(ASP.NET MVC 1.0)使用。 在mvc contrib项目中有一个叫做“RescueAttribute”的精彩属性,你也许应该检查一下;)

 [HandleError] 

当你只向你的类(或者你的操作方法)提供HandleError属性时,当一个未处理的exception发生时,MVC将首先在Controller的View文件夹中查找一个名为“Error”的相应View。 如果找不到它,那么它将继续查看共享视图文件夹(默认情况下它应该有一个Error.aspx文件)

 [HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")] [HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")] 

您还可以将其他属性与您正在查找的exceptiontypes的特定信息进行叠加。 此时,您可以将错误指向除默认“错误”视图以外的特定视图。

欲了解更多信息,请看Scott Guthrie的博客文章 。

还应该注意的是,错误不会将http错误代码设置为500

(例如,UnauthorizedAccessException)

将不会被HandleErrorfilter处理。

解决schemehttp错误代码为500,这是一个名为[错误]的属性把它放在一个动作

 public class Error: System.Web.Mvc.HandleErrorAttribute { public override void OnException(System.Web.Mvc.ExceptionContext filterContext) { if (filterContext.HttpContext.IsCustomErrorEnabled) { filterContext.ExceptionHandled = true; } base.OnException(filterContext); //OVERRIDE THE 500 ERROR filterContext.HttpContext.Response.StatusCode = 200; } private static void RaiseErrorSignal(Exception e) { var context = HttpContext.Current; // using.Elmah.ErrorSignal.FromContext(context).Raise(e, context); } } 

//例:

 [Error] [HandleError] [PopulateSiteMap(SiteMapName="Mifel1", ViewDataKey="Mifel1")] public class ApplicationController : Controller { } 

MVC中的属性在get和post方法的error handling中非常有用,它也跟踪ajax调用

在您的应用程序中创build一个基本控制器,并在您的主控制器(EmployeeController)中inheritance它。

公共类EmployeeController:BaseController

在基本控制器中添加以下代码。

 /// <summary> /// Base Controller /// </summary> public class BaseController : Controller { protected override void OnException(ExceptionContext filterContext) { Exception ex = filterContext.Exception; //Save error log in file if (ConfigurationManager.AppSettings["SaveErrorLog"].ToString().Trim().ToUpper() == "TRUE") { SaveErrorLog(ex, filterContext); } // if the request is AJAX return JSON else view. if (IsAjax(filterContext)) { //Because its a exception raised after ajax invocation //Lets return Json filterContext.Result = new JsonResult() { Data = Convert.ToString(filterContext.Exception), JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } else { filterContext.ExceptionHandled = true; filterContext.HttpContext.Response.Clear(); filterContext.Result = new ViewResult() { //Error page to load ViewName = "Error", ViewData = new ViewDataDictionary() }; base.OnException(filterContext); } } /// <summary> /// Determines whether the specified filter context is ajax. /// </summary> /// <param name="filterContext">The filter context.</param> private bool IsAjax(ExceptionContext filterContext) { return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest"; } /// <summary> /// Saves the error log. /// </summary> /// <param name="ex">The ex.</param> /// <param name="filterContext">The filter context.</param> void SaveErrorLog(Exception ex, ExceptionContext filterContext) { string logMessage = ex.ToString(); string logDirectory = Server.MapPath(Url.Content("~/ErrorLog/")); DateTime currentDateTime = DateTime.Now; string currentDateTimeString = currentDateTime.ToString(); CheckCreateLogDirectory(logDirectory); string logLine = BuildLogLine(currentDateTime, logMessage, filterContext); logDirectory = (logDirectory + "\\Log_" + LogFileName(DateTime.Now) + ".txt"); StreamWriter streamWriter = null; try { streamWriter = new StreamWriter(logDirectory, true); streamWriter.WriteLine(logLine); } catch { } finally { if (streamWriter != null) { streamWriter.Close(); } } } /// <summary> /// Checks the create log directory. /// </summary> /// <param name="logPath">The log path.</param> bool CheckCreateLogDirectory(string logPath) { bool loggingDirectoryExists = false; DirectoryInfo directoryInfo = new DirectoryInfo(logPath); if (directoryInfo.Exists) { loggingDirectoryExists = true; } else { try { Directory.CreateDirectory(logPath); loggingDirectoryExists = true; } catch { } } return loggingDirectoryExists; } /// <summary> /// Builds the log line. /// </summary> /// <param name="currentDateTime">The current date time.</param> /// <param name="logMessage">The log message.</param> /// <param name="filterContext">The filter context.</param> string BuildLogLine(DateTime currentDateTime, string logMessage, ExceptionContext filterContext) { string controllerName = filterContext.RouteData.Values["Controller"].ToString(); string actionName = filterContext.RouteData.Values["Action"].ToString(); RouteValueDictionary paramList = ((System.Web.Routing.Route)(filterContext.RouteData.Route)).Defaults; if (paramList != null) { paramList.Remove("Controller"); paramList.Remove("Action"); } StringBuilder loglineStringBuilder = new StringBuilder(); loglineStringBuilder.Append("Log Time : "); loglineStringBuilder.Append(LogFileEntryDateTime(currentDateTime)); loglineStringBuilder.Append(System.Environment.NewLine); loglineStringBuilder.Append("Username : "); loglineStringBuilder.Append(Session["LogedInUserName"]); loglineStringBuilder.Append(System.Environment.NewLine); loglineStringBuilder.Append("ControllerName : "); loglineStringBuilder.Append(controllerName); loglineStringBuilder.Append(System.Environment.NewLine); loglineStringBuilder.Append("ActionName : "); loglineStringBuilder.Append(actionName); loglineStringBuilder.Append(System.Environment.NewLine); loglineStringBuilder.Append("----------------------------------------------------------------------------------------------------------"); loglineStringBuilder.Append(System.Environment.NewLine); loglineStringBuilder.Append(logMessage); loglineStringBuilder.Append(System.Environment.NewLine); loglineStringBuilder.Append("=========================================================================================================="); return loglineStringBuilder.ToString(); } /// <summary> /// Logs the file entry date time. /// </summary> /// <param name="currentDateTime">The current date time.</param> string LogFileEntryDateTime(DateTime currentDateTime) { return currentDateTime.ToString("dd-MMM-yyyy HH:mm:ss"); } /// <summary> /// Logs the name of the file. /// </summary> /// <param name="currentDateTime">The current date time.</param> string LogFileName(DateTime currentDateTime) { return currentDateTime.ToString("dd_MMM_yyyy"); } } 

================================================

查找目录:Root / App_Start / FilterConfig.cs

添加以下代码:

 /// <summary> /// Filter Config /// </summary> public class FilterConfig { /// <summary> /// Registers the global filters. /// </summary> /// <param name="filters">The filters.</param> public static void RegisterGlobalFilters(GlobalFilterCollection filters) { filters.Add(new HandleErrorAttribute()); } } 

跟踪AJAX错误:

在布局页面加载中调用CheckAJAXError函数。

 function CheckAJAXError() { $(document).ajaxError(function (event, jqXHR, ajaxSettings, thrownError) { var ex; if (String(thrownError).toUpperCase() == "LOGIN") { var url = '@Url.Action("Login", "Login")'; window.location = url; } else if (String(jqXHR.responseText).toUpperCase().indexOf("THE DELETE STATEMENT CONFLICTED WITH THE REFERENCE CONSTRAINT") >= 0) { toastr.error('ReferanceExistMessage'); } else if (String(thrownError).toUpperCase() == "INTERNAL SERVER ERROR") { ex = ajaxSettings.url; //var url = '@Url.Action("ErrorLog", "Home")?exurl=' + ex; var url = '@Url.Action("ErrorLog", "Home")'; window.location = url; } }); }; 

您缺lessError.aspx :)在预览5,这是位于您的视图/共享文件夹。 只需从新的预览版5项目复制即可。

  [HandleError] public class ErrorController : Controller { [AcceptVerbs(HttpVerbs.Get)] public ViewResult NotAuthorized() { //401 Response.StatusCode = (int)HttpStatusCode.Unauthorized; return View(); } [AcceptVerbs(HttpVerbs.Get)] public ViewResult Forbidden() { //403 Response.StatusCode = (int)HttpStatusCode.Forbidden; return View(); } [AcceptVerbs(HttpVerbs.Get)] public ViewResult NotFound() { //404 Response.StatusCode = (int)HttpStatusCode.NotFound; return View(); } public ViewResult ServerError() { //500 Response.StatusCode = (int)HttpStatusCode.NotFound; return View(); } 

}

Interesting Posts