无法在页面卸载事件中调用post到asp.net页面

时间:2014-04-07 15:29:09

标签: jquery asp.net ajax server-side

我正在尝试在使用框架集的遗留应用程序中工作。我试图从页面卸载事件中激活服务器端代码。以下是一些演示此问题的示例代码。

Default.aspx的:

<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Default.aspx.cs" Inherits="SimpleTest._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<frameset rows="20%,80%">
    <frame name="Frame2" src="Frame2.aspx">
        <frameset>
            <frame name="Frame1" src="Frame1.aspx">
    </frameset>
</frameset>
</html>

Frame2.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Frame2.aspx.cs" Inherits="SimpleTest.Frame2" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
    <div>
        <asp:Button ID="btnSecond" runat="server" Text="Button Second" onclick="btnSecond_Click" /> 
    </div>
</form>
<script type="text/javascript">
    if ('onbeforeunload' in window) {
        window.onbeforeunload = (function () { clearSessionData(); });
    } else {
        if ('onunload' in window) {
            window.onunload = (function () { clearSessionData(); });
        }
    }

    function clearSessionData() {
        alert("clearSessionData fired!");
        $.ajax({
            type: "POST",
            url: "Frame2.aspx/someFunction",
            success: function () { alert("SUCCESS"); },
            error: function () { alert("ERROR"); }
        });
    }
</script>
</body>
</html>

Frame2.aspx.cs:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace SimpleTest
{
    public partial class Frame2 : System.Web.UI.Page
    {
        protected void btnSecond_Click(object sender, EventArgs e)
        {
            int test = 1;
            test++;
        }

        protected void someFunction()
        {
            int test = 1;
            test++;
        }
    }
}

我没有包含Frame1.aspx的代码,因为在此示例中该页面为空。

如果我运行此测试代码,则会显示“clearSessionData已触发!”的警告。运行,并显示警告框。但是,下一行不会触发服务器功能“someFunction”。

我也试过使用$ .post()而不是$ .ajax()但是,也没有运气。有任何人对此有经验吗?尝试使用jQuery从框架集中激活服务器端代码是否有问题?你会如何使用jQuery或任何其他方法实现这一目标?我尝试了几个选项,但似乎没有任何东西可以解雇服务器端代码。

任何建议都会受到赞赏。

感谢。

添加评论:

作为旁注,如果我有一个简单的页面,没有框架,我可以将代码放在按钮的服务器端点击事件中,然后创建一个Javascript函数,使用jQuery的“触发器”方法来调用按钮的服务器 - 侧面点击代码没有任何问题。请参阅此示例代码:

<body>
<form id="form1" runat="server">
<div>
    <asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
</div>
</form>
<script type="text/javascript">
    if ('onbeforeunload' in window) {
        window.onbeforeunload = (function () { clearSessionData(); });
    } else {
        if ('onunload' in window) {
            window.onunload = (function () { clearSessionData(); });
        }
    }

    function clearSessionData() {
        $("#Button1").trigger("click");
    }
</script>

这很好用,当浏览器关闭时触发click事件代码(以及其他触发卸载的事件)。但是,无论出于何种原因,使用框架打破了所有这一切。

1 个答案:

答案 0 :(得分:1)

您需要将someFunction(在服务器上)转换为页面方法。可以通过AJAX调用从客户端代码调用页面方法。

这是一篇解释如下的文章:http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/

基本上,您使用WebMethod和ScriptMethod属性修饰方法。另外,公开一下:

[WebMethod, ScriptMethod]    
public static void someFunction()
{
    int test = 1;
    test++;
}

这些将需要使用System.Web.Services和System.Web.Script.Services。

的语句

更新:我刚看到您更新的问题,说您使用的是.NET 2.0。如果您不能使用页面方法,这是一个解决方法。首先,创建一个Generic HttpHandler。我打电话给我的KillSession.ashx。请注意,您还必须实现标记接口 IRequiresSessionState 才能访问HttpSession。

KillSession.ashx.cs:

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.SessionState;

namespace TestFrames
{
    /// <summary>
    /// Summary description for KillSession
    /// </summary>
    public class KillSession : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            if (context.Session != null)
            {
                context.Session.Clear();
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

在Default.aspx(框架容器)中添加一个名为killSession的函数。请注意它调用KillSession.ashx:

<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="Default.aspx.cs" Inherits="SimpleTest._Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
    <script>
        function killSession() {
            console.log("Killing Session");
            $.ajax({
                type: "POST",
                url: "KillSession.ashx",
                success: function () { alert("SUCCESS"); },
                error: function () { alert("ERROR"); }
            });
        }
    </script>
</head>
<frameset rows="20%,80%">
    <frame name="Frame2" src="Frame2.aspx">
        <frameset>
            <frame name="Frame1" src="Frame1.aspx">
    </frameset>
</frameset>
</html>

然后从您的框架页面(例如Frames2.aspx):

<script type="text/javascript">
    if ('onbeforeunload' in window) {
        window.onbeforeunload = (function () { clearSessionData(); });
    } else {
        if ('onunload' in window) {
            window.onunload = (function () { clearSessionData(); });
        }
    }

    function clearSessionData() {
        alert("clearSessionData fired!");
        if (typeof window.top.killSession === "function") {
            window.top.killSession();
        }
    }
</script>

只要帧内有卸载事件,这将调用顶级帧(Default.aspx)killSession函数。