我如何[HandleError]
在asp.net MVC Preview 5中进行过滤?
我在我的Web.config文件中设置了customErrors
并将[HandleError]放在我的Controller类上面,如下所示:
[HandleError] public class DSWebsiteController: Controller { [snip] public ActionResult CrashTest() { throw new Exception("Oh Noes!"); } }
然后我让我的控制器从这个类继承并在它们上调用CrashTest().视觉工作室在错误时停止并按下f5继续后,我被重新路由到Error.aspx?aspxerrorpath =/sxi.mvc/CrashTest(其中sxi是所用控制器的名称.当然道路无法找到,我得到"'''应用程序中的服务器错误."404.
这个站点从预览3移植到5.除了错误处理之外,所有东西都运行(没有太多工作要移植).当我创建一个完整的新项目时,错误处理似乎有效.
想法?
- 注意 -
由于这个问题现在有超过3K的视图,我认为放入我目前使用的(ASP.NET MVC 1.0)是有益的.在mvc contrib项目中有一个名为"RescueAttribute"的出色属性你也应该检查一下;)
[HandleError]
当你只为你的类提供HandleError属性时(或者你的动作方法),当发生未处理的异常时,MVC将首先在Controller的View文件夹中查找名为"Error"的相应视图.如果它找不到它,那么它将继续查看共享视图文件夹(默认情况下应该包含Error.aspx文件)
[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")] [HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")]
您还可以使用有关所查找的异常类型的特定信息来堆叠其他属性.此时,您可以将错误定向到默认"错误"视图以外的特定视图.
有关更多信息,请查看Scott Guthrie关于它的博客文章.
还应注意,未将http错误代码设置为500的错误
(例如UnauthorizedAccessException)
HandleError过滤器不会处理.
将http错误代码解为500这是一个名为[ERROR]的属性,将其置于一个动作上
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方法的错误处理中非常有用,它还跟踪ajax调用.
在应用程序中创建一个基本控制器,并在主控制器(EmployeeController)中继承它.
public class EmployeeController:BaseController
在基本控制器中添加以下代码.////// Base Controller /// 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); } } ////// Determines whether the specified filter context is ajax. /// /// The filter context. private bool IsAjax(ExceptionContext filterContext) { return filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest"; } ////// Saves the error log. /// /// The ex. /// The filter context. 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(); } } } ////// Checks the create log directory. /// /// The log path. 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; } ////// Builds the log line. /// /// The current date time. /// The log message. /// The filter context. 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(); } ////// Logs the file entry date time. /// /// The current date time. string LogFileEntryDateTime(DateTime currentDateTime) { return currentDateTime.ToString("dd-MMM-yyyy HH:mm:ss"); } ////// Logs the name of the file. /// /// The current date time. string LogFileName(DateTime currentDateTime) { return currentDateTime.ToString("dd_MMM_yyyy"); } }
================================================
查找目录:Root/App_Start/FilterConfig.cs
添加以下代码:
////// Filter Config /// public class FilterConfig { ////// Registers the global filters. /// /// The filters. 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; } }); };