为什么asp页面加载事件会再次在javascript window.close上触发?

时间:2017-05-05 14:03:15

标签: javascript asp.net vb.net webforms

我有一个程序,我们正在使用外部提供的培训视频和考试来升级新法规的培训。它包括最后的考试。

我被要求将其拆分到我们的ASP员工站点,我已经基本上成功了。我确实想要捕获考试成绩,所以,尽管我有基本的Javascripting技能,但我确实在Javascript编码中找到了计算考试成绩的地方,所以我让Javascript打开一个asp.net页面作为弹出窗口,将考试成绩信息传递给该页面,页面将结果记录在数据库中。页面上的唯一项目是确认已记录信息,显示捕获的信息以及用于关闭弹出窗口的按钮,该按钮将触发Javascript window.close事件。按下按钮时,将再次记录分数,这应仅在Page Load事件中发生。

我们收到数据库的重复条目,但条目的时间戳不一样,所以我知道部分代码正在运行。

以下是该弹出窗口的asp标记:

<body>
<form id="form1" runat="server">
<div>
    <h4><asp:Label runat="server" ID="lblWelMess" /></h4>
    <br />
    <br />
    <asp:Button runat="server" Text="OK" ID="btnOK" />
</div>
</form>

这是Visual Basic Code Behind -

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim quizName As String = Request.QueryString("qn")
    Dim corrAns As Integer = CInt(Request.QueryString("ca"))
    Dim totQues As Integer = CInt(Request.QueryString("nq"))
    Dim examStatus As String = Request.QueryString("xst")

    logScores(quizName, examStatus, corrAns, totQues)

End Sub

Protected Sub logScores(ByVal qName As String, xStat As String, correct As Integer, qNum As Integer)
    Dim uID As String = Session.Item("USERNAME")
    Dim uName As String = Session.Item("FULLNAME")
    Dim testPerc As String = Format(100 * correct / qNum, "0.00")

    Dim connSQL As New SqlConnection(ConfigurationManager.ConnectionStrings("MyConnectionString1").ToString)
    Dim procName As String = "AddExamScore"
    Dim cmdAdd As New SqlCommand(procName, connSQL)
    cmdAdd.CommandType = CommandType.StoredProcedure
    cmdAdd.Parameters.AddWithValue("UserID", uID)
    cmdAdd.Parameters.AddWithValue("corrAns", correct)
    cmdAdd.Parameters.AddWithValue("numQues", qNum)
    cmdAdd.Parameters.AddWithValue("corrPerc", CDec(testPerc))
    cmdAdd.Parameters.AddWithValue("status", xStat)
    cmdAdd.Connection.Open()

    cmdAdd.ExecuteNonQuery()
    cmdAdd.Connection.Close()

    lblWelMess.Text = uName & ", your score has been logged" & "<br />Quiz: " & qName & "<br />Status: " & xStat & "<br />Correct: " & correct.ToString & "<br />Questions: " & qNum.ToString & "<br />Percentage: " & testPerc
End Sub

Protected Sub btn_OK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
    Response.Write("<Script language=javascript>window.close()</Script>")
End Sub

我应该关闭该窗口还是以其他方式构建按钮单击事件?

我应该在“logScores”子程序中包含某种代码,检查以确保窗口关闭不会触发它吗?

我是否应该将“logScores”子移动到另一个事件?

2 个答案:

答案 0 :(得分:2)

我敢打赌,使用IsPostBack确定它是否是初始请求会解决您的问题。

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    if !IsPostBack Then Begin
        Dim quizName As String = Request.QueryString("qn")
        Dim corrAns As Integer = CInt(Request.QueryString("ca"))
        Dim totQues As Integer = CInt(Request.QueryString("nq"))
        Dim examStatus As String = Request.QueryString("xst")
        logScores(quizName, examStatus, corrAns, totQues)
    EndIf
End Sub

答案 1 :(得分:2)

大多数ASP.NET Web窗体控件都会导致回发,例如单击按钮时。这会强制页面重新加载。您可以检查它是否是PostBack,但这很愚蠢。为什么需要回发来关闭页面?为什么你需要一个服务器控件?

相反,让我们替换所有这些:

<asp:Button runat="server" Text="OK" ID="btnOK" />

Protected Sub btn_OK_Click(sender As Object, e As EventArgs) Handles btnOK.Click
    Response.Write("<Script language=javascript>window.close()</Script>")
End Sub

用这个:

<button onclick="window.close()">OK</button>

不同之处在于,您的原始方式导致某些JavaScript触发,从而导致HTTP Post到服务器,在整个页面生命周期中运行,构建新的页面实例,运行按钮单击处理程序,编写一些JavaScript到一旦它到达那个JavaScript就会导致它关闭窗口的页面。

我的方式可以描述为:当点击按钮并关闭窗口时,某些JavaScript会触发。

请注意,像这样的东西就是为什么像我这样的人不喜欢Web Forms。它可能看起来很容易,但一切都比看上去复杂得多。相反,学习HTML和JavaScript的基础知识,将为您提供更好的服务。最好使用ASP.NET MVC,它可以减少这种泄漏的抽象内容。或者切换到在客户端上编写HTML和JavaScript(可能使用Angular或React或Knockout等),通过AJAX(可能使用ASP.NET Web API)或Web套接字(可能使用SignalR)与Web服务器进行通信。这样的抽象漏洞更少,HTML更清晰,更容易调试,对客户来说更快,对客户端和服务器来说资源消耗更少。

我不是说你不能使用Web Forms并获得成功。就像罗斯的回答所显示的那样,通常有办法做事。但那里有更好的方法。