2011-12-15 8 views
5

He creado una aplicación ASP.NET MVC 3, usando httpErrors para manejar la visualización de mensajes de error y similares para el usuario. Ese código funciona bien, y está duplicado a continuación.Pasando la excepción a la página de error personalizado utilizando IIS7 httpErrors

<httpErrors existingResponse="Replace" defaultResponseMode="ExecuteURL" errorMode="Custom"> 
    <clear/> 
    <error statusCode="403" path="/Error/Forbidden" responseMode="ExecuteURL"/> 
    <error statusCode="404" subStatusCode="-1" path="/Error/NotFound" responseMode="ExecuteURL"/> 
    <error statusCode="500" subStatusCode="-1" path="/Error/ServerError" responseMode="ExecuteURL"/> 
</httpErrors> 

Cuando se produce una excepción en un controlador, BaseController.OnException se activa (BaseController es una clase de mi propia creación). Lo que quiero hacer en esa función es almacenar la excepción para que mi acción ServerError pueda ver su tipo y mensaje para determinar qué mostrar al usuario. El método completo se copia a continuación.

protected override void OnException(ExceptionContext filterContext) 
{ 
    // doesn't work 
    this.TempData["exception"] = filterContext.Exception; 

    // doesn't work 
    this.Session["exception"] = filterContext.Exception; 

    // temporary hack 
    ErrorController.RequestExceptions[this.Request.UserHostAddress] = filterContext.Exception; 
    base.OnException(filterContext); 
} 

Cuando la solicitud llega a la ErrorController instancia (ErrorController está en un espacio de nombres diferentes, pero no creo que sea relevante), por alguna razón Server.GetLastError() vuelve nulo, TempData está vacía, la sesión está vacío, y Session.IsNewSession es verdad. Traté de solucionar el problema haciendo que la aplicación almacenara algún tipo de ID de solicitud, pero eso no parece existir, y en este momento la mejor solución que tengo es esta extremadamente hacky "almacenarla solicitando IP, luego eliminar tan pronto como el ErrorController lo haya recogido ".

Esto (sorprendentemente) funciona, pero tiene que haber una solución más segura y escalable. No estoy seguro de por qué se borra TempData o por qué se reinicia la sesión, ¿es por el error o esto cuenta como dos solicitudes separadas? De todos modos, ¿hay alguna solución para obtener el comportamiento deseado?

P.S. Preferiría, si fuera posible, utilizar la entrada httpErrors en web.config en lugar de código en Application_Error: parece una solución más limpia y más declarativa.

P.P.S. Encontré un artículo sobre problemas con el objeto Session durante las redirecciones (link) pero dice que el problema se ha solucionado. La mayoría de las otras cosas que he encontrado han sido sobre el viejo sistema customErrors, pero voy a seguir buscando.

+0

Cualquier noticia sobre por qué la sesión se borra. Estoy teniendo exactamente el mismo problema. Tanques –

Respuesta

2

MVC tiene un soporte incorporado para manejar Excepciones y mostrar una vista personalizada. De forma predeterminada, MVC agrega HandleErrorAttribute al método RegisterGlobalFilters en el archivo Global.asax.cs.

public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
    } 

es necesario agregar una vista llamada Error a la carpeta Shared vista. La vista tendrá un modelo de tipo HandleErrorInfo que, como una propiedad denominada Exception para conseguir la excepción lanzada

@model System.Web.Mvc.HandleErrorInfo 

@Model.Exception.Message 
+0

Entonces, ¿los 'httpErrors' son confusos, o están destinados a algún otro propósito que no entiendo? – ehdv

+0

@ehdv MVC se ejecuta en la parte superior del tiempo de ejecución de Asp.Net. Si MVC lanza una excepción (y usted no la maneja en MVC) será manejada por el tiempo de ejecución de Asp.Net utilizando el controlador apropiado 'httpErrors'. – Eranga

Cuestiones relacionadas