Pregunta

Trabajo en una universidad y he estado desarrollando un sitio ASP.NET con muchos, muchos informes sobre estudiantes, estadísticas de asistencia...La base de los datos es una base de datos de servidor MSSQL que es el back-end de nuestro sistema de gestión de estudiantes.Tiene un período de mantenimiento regular los jueves por la mañana durante un período de tiempo desconocido (dependiendo de lo que se deba hacer).

La mayoría del personal es consciente de esto, pero los usuarios menos habituales parecen estar llamándome constantemente.¿Cuál es la forma más fácil de deshabilitar el sitio durante el mantenimiento? Obviamente, puedo probar una consulta de base de datos para comprobar si está activo, pero no estoy seguro de cuál es la mejor manera de, por ejemplo, redirigir a todos los usuarios al mensaje "El sitio web está inactivo por mantenimiento". teniendo en cuenta que podrían haber iniciado una sesión antes de que el sitio web cayera.

Con suerte, algo se puede implementar globalmente en lugar de por página.

¿Fue útil?

Solución

Sugeriría hacerlo en Application_PreRequestHandlerExecute en lugar de hacerlo después de que se produzca un error.Generalmente, sería mejor no ingresar al procesamiento normal si sabe que su base de datos no está disponible.Normalmente uso algo como a continuación

void Application_PreRequestHandlerExecute(Object sender, EventArgs e)
{
 string sPage = Request.ServerVariables["SCRIPT_NAME"];
 if (!sPage.EndsWith("Maintenance.aspx", StringComparison.OrdinalIgnoreCase))
 {
  //test the database connection
  //if it fails then redirect the user to Maintenance.aspx
  string connStr = ConfigurationManager.ConnectionString["ConnectionString"].ConnectionString;
  SqlConnection conn = new SqlConnection(connStr);
  try
  {
   conn.Open();
  }
  catch(Exception ex)
  {
   Session["DBException"] = ex;
   Response.Redirect("Maintenance.aspx");
  }
  finally
  {
   conn.Close();
  }
 }
}

Otros consejos

Coloque un archivo html llamado "app_offline.htm" en la raíz de su directorio virtual.Simple como eso.

Scott Guthrie sobre el tema y errores amistosos.

Puede mostrar un mensaje a las personas que iniciaron sesión diciendo "el sitio estará inactivo por mantenimiento en xxx minutos" y luego ejecutar un servicio para cerrar la sesión de todos después de xxx minutos.Luego, establezca una marca en algún lugar al que todas las páginas puedan acceder, y en la parte superior de cada página (o solo en la página de la plantilla) pruebe si esa marca está configurada; si lo está, envíe un encabezado de redireccionamiento a un sitio que está inactivo por mantenimiento.

¿Qué sucede ahora cuando el sitio no funciona y alguien intenta acceder a él?¿ADO.NET genera una excepción específica que podría detectar y luego redirigir a la página "sitio web inactivo"?

Puede agregar un archivo "Global.asax" al proyecto y, en su código subyacente, agregar un controlador de eventos "Application_Error".Se activará cada vez que se produzca una excepción y no se detecte, desde cualquier lugar de su aplicación web.Por ejemplo, en C#:

protected void Application_Error(object sender, EventArgs e)
{
    Exception e = Server.GetLastError().GetBaseException();
    if(e is SqlException)
    {    
        Server.ClearError();
        Server.Transfer("~/offline.aspx");
    }
} 

También puede verificar la propiedad Número en la excepción, aunque no estoy seguro de qué números indicarían que no se pudo conectar al servidor de la base de datos.Puede probar esto mientras está inactivo, encontrar el número de error de SQL y buscarlo en línea para ver si es específicamente lo que realmente desea verificar.

EDITAR: Ya veo lo que estás diciendo, petebob.

La página "offline.html" no funcionará si el usuario ya estaba navegando dentro del sitio, o si está accediendo al sitio desde un marcador/enlace externo a una página específica.

La solución que uso es crear un segundo sitio web con la misma dirección (IP o encabezado(s) de host), pero tenerlo deshabilitado de forma predeterminada.Cuando el sitio web no funciona, un script desactiva el sitio web "real" y habilita el sitio web de "mantenimiento".Cuando vuelve a estar en línea, otro script vuelve al sitio web "real".

El sitio web de "mantenimiento" está ubicado en un directorio raíz diferente, con una sola página con el mensaje (y cualquier archivo de imagen/css requerido)

Para que se muestre el mismo mensaje en cualquier página, el sitio web de "mantenimiento" está configurado con un controlador de errores 404 que redirigirá cualquier solicitud a la misma página "el sitio web está inactivo por mantenimiento".

Una versión un poco más elegante de la verificación de la base de datos en cada página sería realizar la verificación en el archivo Global.asax o crear una página maestra de la que heredan todas las demás páginas.

La sugerencia de tener un sitio en línea y un sitio fuera de línea es realmente buena, pero sólo es aplicable si tiene un número limitado de sitios para administrar en el servidor.

EDITAR: Maldita sea, las otras respuestas con estas sugerencias surgieron después de que cargué la página.Necesito recordar actualizar antes de responder :)

El código de James se olvida de cerrar la conexión, probablemente debería ser:

try
{
   conn.Open();
}
catch(Exception ex)
{
   Session["DBException"] = ex;
   Response.Redirect("Maintenance.aspx");
}
finally
{
   conn.Close();
}

Gracias por las respuestas hasta ahora. Debo señalar que no soy yo quien hace el mantenimiento ni tengo acceso todo el tiempo a IIS.Además, prefiero opciones en las que no hago nada porque, como todos los programadores, soy un poco vago.

Sé que una forma es marcar una bandera en cada página, pero espero evitarlo.¿No podría hacer algo con la página global.asax? De hecho, creo que publicar ha ocupado mi cerebro:

Creo que podría poner un poco de código en Application_BeginRequest para verificar el estado de SQL y luego redirigir:

HttpContext context = HttpContext.Current;
     if (!isOnline())
     {
        context.Response.ClearContent();
        context.Response.Write("<script language='javascript'>" + 
"top.location='" + Request.ApplicationPath + "/public/Offline.aspx';</scr" + "ipt>");
     } 

O algo así puede que no sea perfecto, aún no lo he probado porque no estoy en el trabajo.Se agradecen los comentarios.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top