sql服务器脱机时(礼节性地)禁用网站
我在大学里工作,一直在开发一个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(); }