2013-05-22 5 views
11

я сделал некоторые изменения в Global.asax, так что я могу показать пользовательские страницы ошибок (403, 404 и 500) Вот код:страницы ошибок не обнаружена, метание ошибки ELMAH с страницами ошибок

public class MvcApplication : System.Web.HttpApplication 
    { 
     protected void Application_Start() 
     { 
      AreaRegistration.RegisterAllAreas(); 

      WebApiConfig.Register(GlobalConfiguration.Configuration); 
      //FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
      RouteConfig.RegisterRoutes(RouteTable.Routes); 
      BundleConfig.RegisterBundles(BundleTable.Bundles); 
     } 

     protected void Application_Error(object sender, EventArgs e) 
     { 
      if (Context.IsCustomErrorEnabled) 
      { 
       ShowCustomErrorPage(Server.GetLastError()); 
      } 
     } 

     private void ShowCustomErrorPage(Exception exception) 
     { 
      HttpException httpException = exception as HttpException; 
      if (httpException == null) 
      { 
       httpException = new HttpException(500, "Internal Server Error", exception); 
      } 

      Response.Clear(); 
      RouteData routeData = new RouteData(); 
      routeData.Values.Add("controller", "Error"); 
      routeData.Values.Add("fromAppErrorEvent", true); 

      switch (httpException.GetHttpCode()) 
      { 
       case 403: 
        routeData.Values.Add("action", "AccessDenied"); 
        break; 

       case 404: 
        routeData.Values.Add("action", "NotFound"); 
        break; 

       case 500: 
        routeData.Values.Add("action", "ServerError"); 
        break; 

       default: 
        routeData.Values.Add("action", "DefaultError"); 
        routeData.Values.Add("httpStatusCode", httpException.GetHttpCode()); 
        break; 
      } 

      Server.ClearError(); 

      IController controller = new ErrorController(); 
      controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData)); 
     } 
    } 

Я также добавил следующее к моему Web.Config:

<customErrors mode="On"> 
    <!-- There is custom handling of errors in Global.asax --> 
</customErrors> 

Обычаем страница ошибок отображается корректно, и ELMAH правильно зарегистрировать ошибку, которая была (целенаправленно) выброшено. Но ELMAH также улавливает и регистрирует дополнительную ошибку:

System.InvalidOperationException: The view 'Error' or its master was not found or no view engine supports the searched locations. The following locations were searched: ~/Views/account/Error.aspx ~/Views/account/Error.ascx ~/Views/Shared/Error.aspx ~/Views/Shared/Error.ascx ~/Views/account/Error.cshtml ~/Views/account/Error.vbhtml ~/Views/Shared/Error.cshtml ~/Views/Shared/Error.vbhtml 

Мои первые инстинкты привели меня к отключению глобальной HandleErrorAttribute в конфигурации фильтра. И аналогичные вопросы SO, такие как: MVC problem with custom error pages, привели меня к тому, что мои подозрения были верны. Но даже после отключения глобального HandleErrorAttribute я все еще получаю сообщение об ошибке, что не удалось найти представление об ошибке! Что дает? Моя единственная другая догадка, что мой базовый контроллер получает от System.Web.Mvc.Controller я попытался исследовать источник, чтобы увидеть, если HandleErrorAttribute применяется к System.Web.Mvc.Controller, но ничего не мог почерпнуть ...

UPDATE: Я пытался перекрывая мой базовый контроллер для отметьте исключения, которые обрабатываются следующим образом:

protected override void OnException(ExceptionContext filterContext) 
{ 
    filterContext.ExceptionHandled = true; 
    base.OnException(filterContext); 
} 

но это не решило проблему.

UPDATE2: Я поместил файл Error.aspx в общие представления, чтобы посмотреть, что произойдет. Когда он там, ELMAH регистрирует принудительное исключение, а затем общий просмотр подаётся вверх - он никогда не достигает Application_Error() .... не слишком уверен, что с ним делать.

ответ

26

Наконец получил это работает к моему удовольствию ...

Пакет Elmah.Mvc применяет «скрытый» обработчик ошибок. Я отключил это, добавив следующую строку в файле web.config <appSettings> (значение было установлено значение «ложь» по умолчанию из NuGet установки)

<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> 

Итак, теперь мои ошибки распространяются до Application_Error и регистрируются в журнале Elmah, минуя фильтр Elmah и отображая правильную страницу ошибки (не тот, что находится в /shared/error.cshtml)

+4

также, убедитесь, что MVC по умолчанию обработчик ошибок удален из FilterConfig – solidau

+1

Это было очень трудно найти ... спасибо. –

+0

http: // beletsky.net/2012/11/elmahmvc-202-is-out.html «Это elmah.mvc.disableHandleErrorFilter. По умолчанию это« false », что означает« HandleErrorAttribute() »из ELMAH.MVC. Чтобы отключить его, просто установите true для этой настройки. " – PussInBoots

1

Если вы работаете в интегрированном режиме IIS 7, вам нужно будет добавить Response.TrySkipIisCustomErrors = true; в Application_Error. В противном случае IIS будет перенаправлять клиента на страницу пользовательских ошибок, несмотря на все, что вы делаете в коде.

Смотрите здесь для получения дополнительной информации: http://www.west-wind.com/weblog/posts/2009/Apr/29/IIS-7-Error-Pages-taking-over-500-Errors

Edit: вот тело моего Application_Error:

if (HttpContext.Current != null) 
{ 
    Server.ClearError(); 
    Response.TrySkipIisCustomErrors = true; 
    RouteData data = new RouteData(); 
    data.Values.Add("controller", "Error"); 
    data.Values.Add("action", "Error"); 
    IController controller = new MyApp.Controllers.ErrorController(); 
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), data)); 
} 
+0

Я попытался добавить это до и после 'Response.Clear();' в 'ShowCustomErrorPage'. Ничего не сработало :( – solidau

+0

также попытался как первая строка в 'Application_Error' – solidau

+1

Попробуйте установить его после' Response.ClearError() '. Вот где у меня есть. – anwright

Смежные вопросы