2012-07-18 13 views
5

Mam aplikację internetową MVC 2, która zbliża się do wydania. Do tej pory miałem wyłączone błędy niestandardowe, ale chciałbym, aby zadziałały, gdy będę gotowy do produkcji.HandleErrorInfo przy użyciu MVC2 - Model jest pusty?

mam skonfigurować web.config z następujących czynności:

<customErrors mode="On" defaultRedirect="/Error/"> 
    <error statusCode="404" redirect="/Error/NotFound "/> 
</customErrors> 

404 z nich działa doskonale i NOTFOUND jest działaniem, które odwzorowuje bezpośrednio do widoku, który tylko pokazuje dość standardową stronę 404 używając mojego własny plik Site.Master.

do niczego innego niż 404, chcę użytkownika, aby móc zobaczyć szczegóły wyjątków. (Jest to aplikacja wewnętrzna i nie ma ryzyka związanego z bezpieczeństwem).

Domyślna akcja ErrorIndex jest ustawiona tak, aby zwróciła zdefiniowaną przez mnie funkcję View(). Czego nie mogę zrozumieć, to jak przekazać informacje o wyjątku do widoku?

To wyglądało obiecująco:

http://devstuffs.wordpress.com/2010/12/12/how-to-use-customerrors-in-asp-net-mvc-2/

Ale kiedy używam widok z:

<%@ Page Title="" Language="C#" 
    MasterPageFile="~/Views/Shared/Bootstrap.Master" 
    Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %> 

Sama strona błędu zgłasza błąd, jak HandleErrorInfo jest null. Oczywiście błąd w niestandardowym błędzie powoduje, że MVC2 ma cały szereg problemów, a wynikiem jest żółty ekran śmierci.

Zgaduję, że albo coś pominąłem w blogu, albo nie wyjaśnia, jak sprawić, aby HandleErrorInfo było niczym innym niż zerą bez ustawiania atrybutu Error dla każdego z moich kontrolerów/akcji.

Ponadto, mam świadomość, że oferty MVC3 z tym lepiej i jestem świadomy Razor jest bardzo dobra. Nie został użyty w tym projekcie ani projekt ten nie zostanie zmieniony, aby go użyć. Więc proszę nie odpowiadaj "Użyj MVC3".

Odpowiedz

12

HandleErrorInfo jest nieważna, ponieważ wykonujesz przekierowanie w customErrors.

To jest pomysł, który próbuję w moim najnowszym projekcie i zaktualizowałem dla MVC 2. Nie używałem customErrors, ponieważ nie mogę wywołać działania kontrolera bez wykonywania przekierowania (chyba).

Błąd aplikacji

protected void Application_Error(Object sender, EventArgs e) 
{ 
    GlobalErrorHandler.HandleError(((HttpApplication)sender).Context, Server.GetLastError(), new ErrorController()); 
} 

Globalny błąd obsługi

public class GlobalErrorHandler 
{ 
    public static void HandleError(HttpContext context, Exception ex, Controller controller) 
    { 
     LogException(ex); 

     context.Response.StatusCode = GetStatusCode(ex); 
     context.ClearError(); 
     context.Response.Clear(); 
     context.Response.TrySkipIisCustomErrors = true; 

     if (IsAjaxRequest(context.Request)) 
     { 
      ReturnErrorJson(context, ex); 
      return; 
     } 

     ReturnErrorView(context, ex, controller); 
    } 

    public static void LogException(Exception ex) 
    { 
     // log the exception 
    } 

    private static void ReturnErrorView(HttpContext context, Exception ex, Controller controller) 
    { 
     var routeData = new RouteData(); 
     routeData.Values["controller"] = "Error"; 
     routeData.Values["action"] = GetActionName(GetStatusCode(ex)); 

     controller.ViewData.Model = new HandleErrorInfo(ex, " ", " "); 
     ((IController)controller).Execute(new RequestContext(new HttpContextWrapper(context), routeData)); 
    } 

    private static void ReturnErrorJson(HttpContext context, Exception ex) 
    { 
     var json = string.Format(@"success: false, error:""{0}""", ex.Message); 
     context.Response.ContentType = "application/json"; 
     context.Response.Write("{" + json + "}"); 
    } 

    private static int GetStatusCode(Exception ex) 
    { 
     return ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500; 
    } 

    private static bool IsAjaxRequest(HttpRequest request) 
    { 
     return request.Headers["X-Requested-With"] != null && request.Headers["X-Requested-With"] == "XMLHttpRequest"; 
    } 

    private static string GetActionName(int statusCode) 
    { 
     string actionName; 

     switch (statusCode) 
     { 
      case 404: 
       actionName = "NotFound"; 
       break; 

      case 400: 
       actionName = "InvalidRequest"; 
       break; 

      case 401: 
       actionName = "AccessDenied"; 
       break; 

      default: 
       actionName = "ServerError"; 
       break; 
     } 

     return actionName; 
    } 

    public static bool IsDebug 
    { 
     get 
     { 
      bool debug = false; 

#if DEBUG 
      debug = true; 
#endif 
      return debug; 
     } 
    } 
} 

kontroler Błąd

public class ErrorController : Controller 
{ 
    public ActionResult AccessDenied() 
    { 
     return View("AccessDenied"); 
    } 

    public ActionResult InvalidRequest() 
    { 
     return View("InvalidRequest"); 
    } 

    public ActionResult NotFound() 
    { 
     return View("NotFound"); 
    } 

    public ActionResult ServerError() 
    { 
     return View("ServerError"); 
    } 
} 

ServerError view

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<System.Web.Mvc.HandleErrorInfo>" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    ServerError 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <h2>ServerError</h2> 

    <% if (Model.Exception != null) { %> 
     <p> 
      Controller: <%= Model.ControllerName %> 
     </p> 
     <p> 
      Action: <%= Model.ActionName %> 
     </p> 
     <p> 
      Message: <%= Model.Exception.Message%> 
     </p> 
     <p> 
      Stack Trace: <%= Model.Exception.StackTrace%> 
     </p> 
    <% } %> 

</asp:Content> 
Powiązane problemy