135 votos

Páginas de error personalizadas en asp.net MVC3

Estoy desarrollando un MVC3 web site de la base y estoy en busca de una solución para la gestión de errores y Representar Vistas personalizadas para cada tipo de error. Así que imagina que tengo un "Error" el Controlador de donde su principal acción es la de "Índice" (error genérico de la página) y este controlador tendrá un par más de las acciones de los errores que pueden aparecer a los usuarios, como "Handle500" o "HandleActionNotFound".

Así que cada error que puede ocurrir en el sitio web pueden ser manejados por el "Error" el Controlador (ejemplos: "Controlador" o "Acción" no se encuentra, 500, 404, dbException, etc.).

Yo estoy usando el archivo de Sitemap para definir el sitio web de rutas (y no de la ruta).

Esta pregunta ya fue contestada, esta es una respuesta a Gweebz

Mi final applicaiton_error método es el siguiente:

protected void Application_Error() {
//while my project is running in debug mode
if (HttpContext.Current.IsDebuggingEnabled && WebConfigurationManager.AppSettings["EnableCustomErrorPage"].Equals("false"))
{
    Log.Logger.Error("unhandled exception: ", Server.GetLastError());
}
else
{
    try
    {
        var exception = Server.GetLastError();

        Log.Logger.Error("unhandled exception: ", exception);

        Response.Clear();
        Server.ClearError();
        var routeData = new RouteData();
        routeData.Values["controller"] = "Errors";
        routeData.Values["action"] = "General";
        routeData.Values["exception"] = exception;

        IController errorsController = new ErrorsController();
        var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
        errorsController.Execute(rc);
    }
    catch (Exception e)
    {
        //if Error controller failed for same reason, we will display static HTML error page
        Log.Logger.Fatal("failed to display error page, fallback to HTML error: ", e);
        Response.TransmitFile("~/error.html");
    }
}
}

193voto

Darin Dimitrov Puntos 528142

Aquí está un ejemplo de cómo manejar errores personalizados. Definir un ErrorsController con acciones de manejo diferentes errores HTTP:

public class ErrorsController : Controller
{
    public ActionResult General(Exception exception)
    {
        return Content("General failure", "text/plain");
    }

    public ActionResult Http404()
    {
        return Content("Not found", "text/plain");
    }

    public ActionResult Http403()
    {
        return Content("Forbidden", "text/plain");
    }
}

y entonces me suscribo para el Application_Error en Global.asax e invocar este controlador:

protected void Application_Error()
{
    var exception = Server.GetLastError();
    var httpException = exception as HttpException;
    Response.Clear();
    Server.ClearError();
    var routeData = new RouteData();
    routeData.Values["controller"] = "Errors";
    routeData.Values["action"] = "General";
    routeData.Values["exception"] = exception;
    Response.StatusCode = 500;
    if (httpException != null)
    {
        Response.StatusCode = httpException.GetHttpCode();
        switch (Response.StatusCode)
        {
            case 403:
                routeData.Values["action"] = "Http403";
                break;
            case 404:
                routeData.Values["action"] = "Http404";
                break;
        }
    }

    IController errorsController = new ErrorsController();
    var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
    errorsController.Execute(rc);
}

18voto

Shaman Puntos 643

Aquí es más artículos cómo crear páginas de error personalizadas con MVC http://kitsula.com/Article/MVC-Custom-Error-Pages.

3voto

Brett Allred Puntos 1993

También puedes hacerlo en el archivo Web.Config. Aquí hay un ejemplo que funciona en IIS 7.5.

     <system.webServer>
          <httpErrors errorMode="DetailedLocalOnly" defaultResponseMode="File">
                <remove statusCode="502" subStatusCode="-1" />
                <remove statusCode="501" subStatusCode="-1" />
                <remove statusCode="412" subStatusCode="-1" />
                <remove statusCode="406" subStatusCode="-1" />
                <remove statusCode="405" subStatusCode="-1" />
                <remove statusCode="404" subStatusCode="-1" />
                <remove statusCode="403" subStatusCode="-1" />
                <remove statusCode="401" subStatusCode="-1" />
                <remove statusCode="500" subStatusCode="-1" />
                <error statusCode="500" path="/notfound.html" responseMode="ExecuteURL" />
                <error statusCode="401" prefixLanguageFilePath="" path="/500.html" responseMode="ExecuteURL" />
                <error statusCode="403" prefixLanguageFilePath="" path="/403.html" responseMode="ExecuteURL" />
                <error statusCode="404" prefixLanguageFilePath="" path="/404.html" responseMode="ExecuteURL" />
                <error statusCode="405" prefixLanguageFilePath="" path="/405.html" responseMode="ExecuteURL" />
                <error statusCode="406" prefixLanguageFilePath="" path="/406.html" responseMode="ExecuteURL" />
                <error statusCode="412" prefixLanguageFilePath="" path="/412.html" responseMode="ExecuteURL" />
                <error statusCode="501" prefixLanguageFilePath="" path="/501.html" responseMode="ExecuteURL" />
                <error statusCode="502" prefixLanguageFilePath="" path="/genericerror.html" responseMode="ExecuteURL" />
           </httpErrors>
</system.webServer>

3voto

Simon_Weaver Puntos 31141

Veo que has añadido una configuración de valor por EnableCustomErrorPage y está también la comprobación IsDebuggingEnabled a determinar si o no para ejecutar su manejo de errores.

Puesto que ya existe un <customErrors/> configuración en ASP.NET (que significa exactamente para este propósito) es más fácil decir simplemente :

    protected void Application_Error()
    {
        if (HttpContext.Current == null) 
        {
                // errors in Application_Start will end up here                
        }
        else if (HttpContext.Current.IsCustomErrorEnabled)
        {
                // custom exception handling
        }
    }

A continuación, en la configuración que usted pondría <customErrors mode="RemoteOnly" /> que es seguro para implementar el estilo, y cuando usted necesita para poner a prueba tu página personalizada de error que usted le daría a <customErrors mode="On" /> para que pueda comprobar que funciona.

Nota también es necesario comprobar si HttpContext.Current es nulo debido a una excepción en Application_Start todavía su este método a pesar de no ser un contexto activo.

2voto

Martin_ATS Puntos 395

Se puede mostrar un error fácil de usar la página con el código de estado http correcto mediante la implementación de Jeff Atwood es Amigable para el Usuario Excepción Manejo de módulo con una ligera modificación para el código de estado http. Funciona sin ningún tipo de redirecciones. Aunque el código es de 2004(!), funciona bien con MVC. Se puede configurar totalmente en el web.config, sin proyecto de MVC cambios de código fuente.

La modificación de la obligación de devolver el original del estado HTTP en lugar de un 200 estado se describe en el post del foro.

Básicamente, en Handler.vb, usted puede agregar algo como:

' In the header...
Private _exHttpEx As HttpException = Nothing

' At the top of Public Sub HandleException(ByVal ex As Exception)...
HttpContext.Current.Response.StatusCode = 500
If TypeOf ex Is HttpException Then
    _exHttpEx = CType(ex, HttpException)
    HttpContext.Current.Response.StatusCode = _exHttpEx.GetHttpCode()
End If

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X