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

为什么asp页面加载事件会在javascript window.close上再次触发?,javascript,asp.net,vb.net,webforms,Javascript,Asp.net,Vb.net,Webforms,我有一个项目,我们使用外部提供的培训视频和考试来升级新法规的培训。最后还包括一次考试 我被要求把这个放到我们的ASP员工网站上,这在很大程度上是成功的。我确实希望捕获考试结果,因此,尽管我掌握了基本的Javascripting技能,但我确实在Javascript编码中找到了计算考试结果的位置,因此我让Javascript打开一个asp.net页面作为弹出窗口,将考试成绩信息传递到该页面,该页面将结果记录在数据库中。页面上唯一的项目是确认信息已被记录,显示捕获的信息,以及关闭弹出窗口的按钮,该按钮

我有一个项目,我们使用外部提供的培训视频和考试来升级新法规的培训。最后还包括一次考试

我被要求把这个放到我们的ASP员工网站上,这在很大程度上是成功的。我确实希望捕获考试结果,因此,尽管我掌握了基本的Javascripting技能,但我确实在Javascript编码中找到了计算考试结果的位置,因此我让Javascript打开一个asp.net页面作为弹出窗口,将考试成绩信息传递到该页面,该页面将结果记录在数据库中。页面上唯一的项目是确认信息已被记录,显示捕获的信息,以及关闭弹出窗口的按钮,该按钮触发Javascript window.close事件。当按下按钮时,将再次记录分数,这只应发生在页面加载事件中

我们得到了数据库的重复条目,但是条目上的时间戳不一样,所以我知道部分代码正在再次运行

以下是该弹出窗口的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代码-

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
Protected Sub Page_Load(ByVal sender作为对象,ByVal e作为System.EventArgs)处理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”)
日志分数(quizName、examStatus、corrAns、totQues)
端接头
受保护的子日志分数(ByVal qName作为字符串,xStat作为字符串,correct作为整数,qNum作为整数)
Dim uID作为字符串=Session.Item(“用户名”)
Dim uName As String=Session.Item(“全名”)
Dim testPerc As String=格式(100*correct/qNum,“0.00”)
Dim connSQL作为新的SqlConnection(ConfigurationManager.ConnectionString(“MyConnectionString1”).ToString)
Dim procName As String=“AddExamScore”
Dim cmdAdd作为新的SqlCommand(procName,connSQL)
cmdAdd.CommandType=CommandType.StoredProcess
cmdAdd.Parameters.AddWithValue(“用户ID”,uID)
cmdAdd.Parameters.AddWithValue(“corrAns”,正确)
cmdAdd.Parameters.AddWithValue(“numQues”,qNum)
cmdAdd.Parameters.AddWithValue(“corrpec”,CDec(testPerc))
cmdAdd.Parameters.AddWithValue(“状态”,xStat)
cmdAdd.Connection.Open()
cmdAdd.ExecuteNonQuery()
cmdAdd.Connection.Close()
lblwelmes.Text=uName&“,您的分数已被记录”&“
测验:&qName&”
状态:&xStat&“
正确:&Correct.ToString&”
问题:&qNum.ToString&“
百分比:&testPerc 端接头 受保护的子btn_确定_单击(发件人作为对象,e作为事件参数)处理btnOK。单击 Response.Write(“window.close()”) 端接头
我应该关闭该窗口还是以其他方式构造按钮单击事件

我是否应该在“logScores”子例程中包含某种代码来检查以确保它不会被关闭的窗口触发


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

我打赌使用iPostBack确定它是否是初始请求将解决您的问题

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

我敢打赌,使用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

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

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

<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

受保护的子btn_确定_单击(发件人作为对象,e作为事件参数)处理btnOK。单击
Response.Write(“window.close()”)
端接头
为此:

<button onclick="window.close()">OK</button>
OK
不同之处在于,您最初的方式会触发一些JavaScript,这会导致向服务器发送HTTP Post,在整个页面生命周期中运行,构建页面的新实例,运行按钮单击处理程序,向页面写入一些JavaScript,一旦点击该JavaScript,就会关闭窗口

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


注意,这就是为什么像我这样的人如此不喜欢Web表单的原因。这看起来可能很简单,但一切都比看上去复杂得多。相反,学习HTML和JavaScript的基础知识将更好地为您服务。最好使用ASP.NETMVC,它可以减少这种泄漏的抽象内容。或者切换到只在客户端编写HTML和JavaScript(可能使用Angular、React或Knockout等),通过AJAX(可能使用ASP.NET web API)或web套接字(可能使用SignalR)与web服务器通信。这就减少了泄漏的抽象、更干净的HTML、更容易调试、客户机更快、客户机和服务器的资源密集度更低


我并不是说你不能使用Web表单并取得成功。就像罗斯的回答所显示的那样,通常有一种做事的方式。但是还有更好的方法。

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

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

<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

受保护的子btn_确定_单击(发件人作为对象,e作为事件参数)处理btnOK。单击
Response.Write(“window.close()”)
端接头
为此:

<button onclick="window.close()">OK</button>
OK
不同之处在于,您最初的方式会触发一些JavaScript,这会导致向服务器发送HTTP Post,贯穿整个页面生命周期,构建页面的新实例,运行您的按钮单击处理程序,