sql服务器脱机时(礼节性地)禁用网站

时间:2020-03-06 14:19:28  来源:igfitidea点击:

我在大学里工作,一直在开发一个ASP.NET网站,其中包含许多有关学生,出勤统计的报告...数据的基础是ms sql服务器数据库,它是我们学生管理系统的后端。这在周四早上有一个定期的维护期,时间未知(取决于必须执行的操作)。

大多数工作人员都知道这一点,但是不那么普通的用户似乎永远困扰着我。显然,在维护期间禁用站点的最简单方法是什么,显然我可以尝试通过数据库查询来测试它是否正常运行,但是不确定例如将所有用户重定向到"该网站已停止维护"消息的最佳方法,请注意,他们可以在网站关闭之前就开始一个会话。

希望可以在全局而不是每页上实现某些功能。

解决方案

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

斯科特·格思里(Scott Guthrie)就这个话题和友善的错误发表了看法。

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

如果用户已经在站点内导航,或者用户正在通过书签/外部链接访问特定页面,则" offline.html"页面将无法工作。

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

"维护"网站位于不同的根目录中,在单个页面上显示消息(以及任何所需的图像/ css文件)

要在任何页面上显示相同的消息,请使用404错误处理程序设置"维护"网站,该错误处理程序会将任何请求重定向到相同的"该网站已关闭维护"页面。

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

我们可以在项目中添加一个" Global.asax"文件,并在其代码后面添加一个" Application_Error"事件处理程序。每当从Web应用程序中的任何地方引发异常并没有捕获到异常时,它就会触发。例如,在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错误号并在线查找,以查看它是否真的是我们要检查的内容。

编辑:我明白你在说什么,皮特勃伯。

到目前为止,感谢答复,我应该指出,我不是负责维护的人,也不能一直访问IIS。另外,我更喜欢我什么都不做的选项,就像所有程序员一样,我有点懒。

我知道一种方法是检查每个页面上的标志,但我希望避免这种情况。我不能对global.asax页面的事实做些什么,我认为发布引起了我的注意:

认为我可以在Application_BeginRequest中放入一些代码来检查sql状态,然后重定向:

HttpContext context = HttpContext.Current;
如果(!isOnline())
{
context.Response.ClearContent();
context.Response.Write("" +" top.location ='" + Request.ApplicationPath +" /public/Offline.aspx';");
}

或者类似的东西可能不是完美的,因为我不在工作,因此尚未经过测试。评论表示赞赏。

我建议在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();
  }
 }
}

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

拥有一个在线站点和一个脱机站点的建议确实不错,但是只有在服务器上要管理的站点数量有限的情况下,该建议才真正适用。

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

James代码忘记了关闭连接,可能应该是:

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