3

我在一所大学工作,一直在开发一个 ASP.NET 站点,其中包含许多关于学生、出勤统计的报告……数据的基础是一个 MSSQL 服务器数据库,它是我们学生管理系统的后端。这在星期四早上有一个定期维护期,持续时间未知(取决于必须做什么)。

大多数员工都知道这一点,但不太经常使用的用户似乎永远在给我打电话。在维护期间禁用站点的最简单方法是什么显然我可以尝试数据库查询来测试它是否已启动但不确定将所有用户重定向到“网站因维护而关闭”消息的最佳方法,请记住,他们本可以在网站关闭之前开始会话。

希望可以在全球范围内而不是在每个页面上实现一些东西。

4

8 回答 8

12

将名为“app_offline.htm”的 html 文件拖放到虚拟目录的根目录中。就那么简单。

Scott Guthrie关于这个主题和友好的错误。

于 2008-09-17T23:53:48.817 回答
1

您可以向已登录的人显示一条消息,说“该站点将在 xxx 分钟内关闭以进行维护”,然后运行一项服务以在 xxx 分钟后将所有人注销。然后在每个页面都可以访问的地方设置一个标志,并在每个页面(或只是模板页面)的顶部测试是否设置了该标志,如果是,则将重定向标头发送到站点已关闭以进行维护页面。

于 2008-09-17T23:57:49.417 回答
1

如果用户已经在站点内导航,或者如果他从书签/外部链接到特定页面访问站点,“offline.html”页面将无法工作。

我使用的解决方案是使用相同的地址(IP 或主机标头)创建第二个网站,但默认情况下将其禁用。当网站关闭时,脚本会停用“真实”网站并启用“维护”网站。当它重新联机时,另一个脚本切换回“真实”网站。

“维护”网站位于不同的根目录中,只有一个页面包含消息(以及任何所需的图像/css 文件)

为了在任何页面上显示相同的消息,“维护”网站设置了一个 404 错误处理程序,它将任何请求重定向到相同的“网站因维护而停机”页面。

于 2008-09-18T00:01:05.977 回答
1

当站点关闭并且有人试图访问它时,现在会发生什么?ADO.NET 是否会引发您可以捕获的特定异常,然后重定向到“网站关闭”页面?

您可以将“Global.asax”文件添加到项目中,并在其代码隐藏中添加“Application_Error”事件处理程序。每当从您的网络应用程序的任何地方抛出异常并且未被捕获时,它都会触发。例如,在 C# 中:

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

您还可以检查异常的 Number 属性,但我不确定哪个数字表示它无法连接到数据库服务器。您可以在它关闭时对其进行测试,找到 SQL 错误号并在线查找它是否是您真正想要检查的具体内容。

编辑:我明白你在说什么,petebob。

于 2008-09-18T00:14:07.287 回答
1

我建议在 Application_PreRequestHandlerExecute 中进行,而不是在发生错误后进行。一般来说,如果您知道您的数据库不可用,最好不要进入正常处理。我通常使用类似下面的东西

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();
  }
 }
}
于 2008-09-18T00:39:18.880 回答
0

感谢到目前为止的回复,我应该指出我不是负责维护的人,也不是一直都可以访问 IIS。此外,我更喜欢我什么都不做的选项,因为我有点懒惰。

我知道一种方法是检查每一页上的标志,但我希望避免它。我能不能对 global.asax 页面做点什么,事实上,我认为发布已经吸引了我的大脑:

想我可以在 Application_BeginRequest 中放入一些代码来检查 SQL 状态然后重定向:

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

或者类似的东西可能不完美,还没有测试,因为我不在工作。评论赞赏。

于 2008-09-18T00:24:16.123 回答
0

每个页面上的数据库检查的稍微更优雅的版本是在 Global.asax 文件中进行检查,或者创建一个所有其他页面都继承自的母版页。

拥有一个在线站点和一个离线站点的建议非常好,但只有当您在服务器上管理的站点数量有限时才真正适用。

编辑:该死的,这些建议的其他答案是在我加载页面后出现的。我需要记得在回复之前刷新:)

于 2008-09-18T00:41:05.413 回答
0

詹姆斯代码忘记关闭连接,应该是:

try
{
   conn.Open();
}
catch(Exception ex)
{
   Session["DBException"] = ex;
   Response.Redirect("Maintenance.aspx");
}
finally
{
   conn.Close();
}
于 2008-09-18T00:44:45.390 回答