按钮有时会重定向到“无法显示此页面”
本文关键字:显示 重定向 按钮 | 更新日期: 2023-09-27 18:22:20
我有一个 ASP.NET 的 c# Web 应用程序发布到我们的服务器上。它由三个页面组成,每个页面上都有一个表单,有点像 3 页登录。验证第三页的表单后,它会将用户发送到其他站点。这里有一个小图表,所以我可以更好地解释它:
姓名页--->出生日期页---> IDNumber页 ---> 其他网站
这在我们所有的开发测试和压力测试中都非常有效。但是,在我们将其投入生产后,偶尔在单击 IDNumberPage 上的"下一步"按钮时,用户会看到带有"诊断连接问题"按钮的"无法显示此页面"。当一个用户发生这种情况时,所有用户都会出现相同的问题(这意味着一旦发生,没有人可以完全进行身份验证(。NamePage和DateOfBirthPage始终有效,当崩溃发生时,IDNumberPage链接不会更改,这表明崩溃发生在应用程序的这一端,而不是在重定向到OtherSite之后。我关闭了友好的HTTP错误,但它没有在页面上显示任何错误。如果我们进入服务器并重新启动应用程序,它会再次工作。
令人沮丧的是,我们无法复制此错误以查看它如何/为什么发生。
一些值得注意的事情:
- 每个页面在 MS SQL 服务器数据库上使用一个查询
- 每个页面最多传递 4 个会话变量(仅包含上一页文本框表单中输入的内容的小字符串(
- 单击最后一个"下一步"按钮时,会话将被放弃。
- 所有结果集/连接/命令在重定向之前关闭。
- 重定向使用重载版本,使用
Response.Redirect(siteName, false)
对不起,如果所有这些都非常模糊,但问题本身在向我们隐瞒方面做得非常好。我们尝试用测试请求(一次多次,在一段时间内多次等(以及登录/尝试破坏页面的不同组合来锤击服务器,但无济于事。任何人都可以建议一些事情来尝试诊断/修复/复制此问题吗?
编辑:导致问题的IDNumberPage代码隐藏上的单击功能:
{ SqlConnection dbconn = new SqlConnection(Application["dbconn"].ToString());
SqlCommand sqlValidate = dbconn.CreateCommand();
dbconn.Open();
sqlValidate.CommandText = "SELECT lastName, csn FROM Demographics WHERE lastName = '" + Session["lastName"].ToString() + "' " +
"AND dob = '" + Session["dobCheck"].ToString() + "' AND mrn = " + strMRN;
SqlDataReader results = sqlValidate.ExecuteReader();
if (results.HasRows)
{
string csn = "";
while (results.Read())
{
if (!String.IsNullOrEmpty(results["csn"].ToString()))
{
csn = results["csn"].ToString();
break;
}
}
string url = Application["surveyUrlString"] + "&lastname=" + Session["lastName"].ToString() + "&mrn=" + strMRN + "&dobday=" + Session["dobday"].ToString()
+ "&dobmonth=" + Session["dobmonth"].ToString() + "&dobyear=" + Session["dobyear"].ToString() + "&csn=" + csn;
results.Close();
dbconn.Close();
Response.Redirect(url, false);
}
该问题是由于 sql 连接泄漏造成的。
您没有正确处置资源。 随着时间的推移,这些将在连接池中堆叠,直到达到池溢出且应用死亡的点。 重置显然可以解决问题。
此外,此问题可能不会显示在"压力"测试中,具体取决于您测试应用程序的方式。
解决方案是重新格式化该代码以更好地处理数据库调用。
{
string url = string.empty;
using (SqlConnection dbconn = new SqlConnection(Application["dbconn"].ToString())) {
using (SqlCommand sqlValidate = dbconn.CreateCommand()) {
dbconn.Open();
sqlValidate.CommandText = "SELECT lastName, csn FROM Demographics WHERE lastName = '" + Session["lastName"].ToString() + "' " +
"AND dob = '" + Session["dobCheck"].ToString() + "' AND mrn = " + strMRN;
using (SqlDataReader results = sqlValidate.ExecuteReader()) {
if (results.HasRows) {
string csn = "";
while (results.Read())
{
if (!String.IsNullOrEmpty(results["csn"].ToString()))
{
csn = results["csn"].ToString();
break;
}
}
url = Application["surveyUrlString"] + "&lastname=" + Session["lastName"].ToString() + "&mrn=" + strMRN + "&dobday=" + Session["dobday"].ToString()
+ "&dobmonth=" + Session["dobmonth"].ToString() + "&dobyear=" + Session["dobyear"].ToString() + "&csn=" + csn;
}
} // sqldatareader
} // using sqlcommand
} // using sqlconnection
if (!String.IsNullOrEmpty(url)) {
Response.Redirect(url, false);
}
}
请注意,在清理完所有内容之前,您不会重定向。
SqlConnection
、SqlCommand
和SqlDataReader
都实现了IDisposable
。 您必须在使用后正确清理,否则资源将被挂起。 执行此操作的"最佳"方法是将它们包装在 using 子句中。 这可确保在退出代码块后正确删除它们,因为它们不会像其他对象那样被垃圾回收。
另请注意,上面的代码有一个很好的附带好处。 也就是说,如果出现错误,它仍然会在您之后清理。 而发布的原始代码在运行查询时如果数据库服务器没有响应或抛出某种类型的错误,则显然会泄漏。
查询可能会出错,具体取决于 dboCheck、姓氏和 mrn 参数中包含的值。 例如,如果为 dobCheck 字段传入了"BOB",或者为 mrn 传入了"什么都没有"怎么办...... 如果 dob 是数据库中的日期时间字段,则查询将引发错误,从而导致连接泄漏。 这样做足够多的次数,您的网站就会关闭。
经过进一步审查,我猜这可能是正在发生的事情:人们正在放入您的应用程序允许达到这一点的垃圾数据,并且查询失败。 这很可能不是您在测试用例中处理过的事情。
旁注:请不要使用 concatentation 创建 sql 语句。 这是一个完全的安全不。 至少,参数化这些查询。
很好的答案克里斯,一个问题不是.使用 语句中缺少 close(( 语句?。对于连接和数据读取器:
results.Close();
} // using sqldatareader
} // using sqlcommand
dbconn.Close();
} // using sqlconnection