Tengo un problema con los errores personalizados en una aplicación ASP.NET MVC que he implementado en mi host compartido. Creé un ErrorController y agregué el siguiente código a Global.asax para capturar las excepciones no controladas, registrarlas y luego transferir el control al ErrorController para mostrar los errores personalizados. Este código se toma de here:Las páginas de error personalizadas de la aplicación ASP.NET MVC no se muestran en el entorno de alojamiento compartido
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Response.Clear();
HttpException httpEx = ex as HttpException;
RouteData routeData = new RouteData();
routeData.Values.Add("controller", "Error");
if (httpEx == null)
{
routeData.Values.Add("action", "Index");
}
else
{
switch (httpEx.GetHttpCode())
{
case 404:
routeData.Values.Add("action", "HttpError404");
break;
case 500:
routeData.Values.Add("action", "HttpError500");
break;
case 503:
routeData.Values.Add("action", "HttpError503");
break;
default:
routeData.Values.Add("action", "Index");
break;
}
}
ExceptionLogger.LogException(ex); // <- This is working. Errors get logged
routeData.Values.Add("error", ex);
Server.ClearError();
IController controller = new ErrorController();
// The next line doesn't seem to be working
controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
}
Application_Error es, sin duda disparando debido a que el registro funciona bien, pero en lugar de mostrar mis páginas de error personalizadas, consigo los genéricos Go Daddy. Del título de la publicación del blog del que se tomó el código anterior, observo que usa Release Candidate 2 del framework MVC. ¿Algo cambió en 1.0 que hace que la última línea de código no funcione? Como de costumbre, es works great on my machine.
Cualquier sugerencia será muy apreciada.
Editar: Olvidé mencionar que probé las 3 posibilidades para el modo CustomErrors en Web.config (Off, On y RemoteOnly). Los mismos resultados independientemente de esta configuración.
Edit 2: Y también lo he probado con y sin la decoración [HandleError] en las clases de Controller.
Actualización: He descubierto y solucionado los 404. Hay una sección del panel de Configuración en el Centro de Control de Alojamiento de Go Daddy donde se puede controlar el comportamiento de 404 y el predeterminado es mostrar su página genérica, y aparentemente esto anula cualquier configuración de Web.config. Así que mi página 404 personalizada ahora se muestra como estaba previsto. Sin embargo, 500s y 503s todavía no están funcionando. Tengo código en el HomeController para agarrar una versión de texto estático del contenido de Si SQL Server genera una excepción de la siguiente manera:
public ActionResult Index()
{
CcmDataClassesDataContext dc = new CcmDataClassesDataContext();
// This might generate an exception which will be handled in the OnException override
HomeContent hc = dc.HomeContents.GetCurrentContent();
ViewData["bodyId"] = "home";
return View(hc);
}
protected override void OnException(ExceptionContext filterContext)
{
// Only concerned here with SqlExceptions so an HTTP 503 message can
// be displayed in the Home View. All others will bubble up to the
// Global.asax.cs and be handled/logged there.
System.Data.SqlClient.SqlException sqlEx =
filterContext.Exception as System.Data.SqlClient.SqlException;
if (sqlEx != null)
{
try
{
ExceptionLogger.LogException(sqlEx);
}
catch
{
// couldn't log exception, continue without crashing
}
ViewData["bodyId"] = "home";
filterContext.ExceptionHandled = true;
HomeContent hc = ContentHelper.GetStaticContent();
if (hc == null)
{
// Couldn't get static content. Display friendly message on Home View.
Response.StatusCode = 503;
this.View("ContentError").ExecuteResult(this.ControllerContext);
}
else
{
// Pass the static content to the regular Home View
this.View("Index", hc).ExecuteResult(this.ControllerContext);
}
}
}
Aquí está el código que intenta buscar el contenido estático:
public static HomeContent GetStaticContent()
{
HomeContent hc;
try
{
string path = Configuration.CcmConfigSection.Config.Content.PathToStaticContent;
string fileText = File.ReadAllText(path);
string regex = @"^[^#]([^\r\n]*)";
MatchCollection matches = Regex.Matches(fileText, regex, RegexOptions.Multiline);
hc = new HomeContent
{
ID = Convert.ToInt32(matches[0].Value),
Title = matches[1].Value,
DateAdded = DateTime.Parse(matches[2].Value),
Body = matches[3].Value,
IsCurrent = true
};
}
catch (Exception ex)
{
try
{
ExceptionLogger.LogException(ex);
}
catch
{
// couldn't log exception, continue without crashing
}
hc = null;
}
return hc;
}
He verificado que si cambio la cadena de conexión para generar una SqlException, el código registra correctamente el error y luego toma y muestra el contenido estático. Pero si también cambio la ruta al archivo de texto estático en Web.config para probar la versión 503 de la Vista de inicio, lo que obtengo es una página con nada más que "servicio no disponible". Eso es. No hay un mensaje 503 personalizado con la apariencia del sitio.
¿Alguien tiene alguna sugerencia sobre mejoras en el código que pueda ayudar? ¿Ayudaría agregar diferentes encabezados a HttpResponse? ¿O es que Go Daddy está secuestrando fuertemente a los 503?
+1 Gracias, Bryan. Después de más de 2 horas de búsqueda, me diste la respuesta que necesitaba. Es tan simple. Estaba intentando establecer un código de error 404 que me daba una excepción de seguridad y "Response.TrySkipIisCustomErrors = true;" arreglado. –
Esto me estaba volviendo loco. Muchas gracias. Colocando "Response.TrySkipIisCustomErrors = true;" Inmediatamente después de configurar los códigos de respuesta en mi controlador de error, fue lo que funcionó para mí. Fue engañoso porque mi instancia local de IIS 7 estaba representando mis vistas de error personalizadas, pero el servidor de almacenamiento remoto no. = P – NovaJoe
Estaba en el mismo barco después de aplicar lo que se proporciona en esta respuesta: http://stackoverflow.com/a/7499406/114029. 'Response.TrySkipIisCustomErrors = true;' viene del cielo! :) –