ASP.NET MVC HandleError
как мне идти о [HandleError]
фильтр внутри asp.net MVC Preview 5?
Я установил 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!");
}
}
затем я позволяю моим контроллерам наследовать от этого класса и вызывать CrashTest() на них. Visual studio останавливается при ошибке, и после нажатия f5 для продолжения я перенаправляюсь на ошибку.aspx?aspxerrorpath=/sxi.mvc / CrashTest (где sxi-имя используемого контроллер. Конечно путь не может быть найден, и я получаю "ошибка сервера в приложении"/"."404.
этот сайт был перенесен с предварительного просмотра 3 на 5. Все работает (не так много работы для порта), кроме обработки ошибок. Когда я создаю совершенно новый проект, обработка ошибок, кажется, работает.
идеи?
--внимание--
Поскольку этот вопрос теперь имеет более 3K просмотров, я подумал, что было бы полезно ввести то, что я сейчас (ASP.NET MVC 1.0) с использованием.
В в MVC contrib на проекте есть блестящий атрибут под названием " RescueAttribute"
Вы, вероятно, должны проверить его тоже ;)
6 ответов:
[HandleError]
когда вы предоставляете только атрибут HandleError вашему классу (или вашему методу действия в этом отношении), то при возникновении необработанного исключения MVC сначала будет искать соответствующее представление с именем "ошибка" в папке представления контроллера. Если он не может найти его там, то он продолжит искать в папке общего вида (которая должна иметь ошибку.aspx файл в нем по умолчанию)
[HandleError(ExceptionType = typeof(SqlException), View = "DatabaseError")] [HandleError(ExceptionType = typeof(NullReferenceException), View = "LameErrorHandling")]
вы также можете складывать дополнительные атрибуты с определенной информацией о тип исключения, который вы ищете. В этот момент Вы можете направить ошибку в определенное представление, отличное от представления "ошибка" по умолчанию.
для получения дополнительной информации, взгляните на сообщение в блоге Скотта Гатри об этом.
следует также отметить, что ошибки, которые не устанавливают код ошибки http 500
(например, UnauthorizedAccessException)
не будет обрабатываться фильтром HandleError.
атрибуты в MVC очень полезны при обработке ошибок в получить и отправить метод, он также трек для ajax call.
создайте базовый контроллер в своем приложении и унаследуйте его в своем главном контроллере(EmployeeController).
public class 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; } }); };
решение для кода ошибки http до 500 это атрибут под названием [ERROR] put it on an action
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 { }
У вас отсутствует ошибка.aspx:) в preview 5 это находится в вашей папке Views/Shared. Просто скопируйте его из нового проекта Preview 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(); }
}