【问题标题】:How to detect a browser refresh from Silverlight 4?如何检测 Silverlight 4 的浏览器刷新?
【发布时间】:2010-09-07 16:24:56
【问题描述】:

我的 Silverlight 4 应用程序通过 wcf 服务与服务器端保持联系。每当用户刷新、导航或终止浏览器时,我都应该对服务器端进行一些清理。

我不能使用应用程序退出事件;我的 wcf 客户端在最终被调用之前就已经死了。我无法使用(SL4 中的新功能)FrameworkElement Unloaded 事件; Silverlight 应用程序关闭时不会调用它。

那么,我如何及时检测浏览器刷新、新页面或关闭来进行清理?

【问题讨论】:

    标签: silverlight


    【解决方案1】:

    巴布,

    当用户离开我的 Silverlight 应用程序(或进行刷新)时,我会执行此操作。请按照以下步骤捕获此事件。

    1.) 首先监听 HTML 页面的“onbeforeunload”事件,像这样......

    public void Application_Startup(object sender, StartupEventArgs e)
    {
        bool ok = HtmlPage.Window.AttachEvent("onbeforeunload", Application_BeforeExit);
        ok = HtmlPage.Document.AttachEvent("onbeforeunload", Application_BeforeExit);
        MainPage mainPage = new MainPage();
        base.RootVisual = mainPage;
    }
    

    2.) 实现 Application_BeforeExit() 以设置和调用 ASP.NET “PageMethod”,如下所示...

    private void Application_BeforeExit(object sender, HtmlEventArgs args)
    {
        string methodName = "ModelShutdown";
        params object[] args = new Guid().ToString());;
    
        try
        {
            ScriptObject pageMethods = (ScriptObject)HtmlPage.Window.GetProperty("PageMethods");
            if (pageMethods == null)
                throw new ArgumentException("Web page does not support PageMethods");
            object[] pageMethodArgs = { new PageMethodEventHandler(Success), new PageMethodEventHandler(Failure), null/*userContext*/};
            object[] combinedArgs = new object[args.Length + pageMethodArgs.Length];
            args.CopyTo(combinedArgs, 0);
            pageMethodArgs.CopyTo(combinedArgs, args.Length);
            pageMethods.Invoke(methodName, combinedArgs);
        }
        catch (Exception ex)
        {
            //ex.Alert();
        }
    }
    

    3.) 将 PageMethod 添加到您的页面代码后面 (Index.aspx.cs),就像这样,

    public partial class Index : Page
    {
        [WebMethod] // a PageMethod called from Silverlight
        public static void ModelShutdown(string identifier)
        {
            System.Diagnostics.Debug.WriteLine("*** Signing Off: " + identifier);
        }
    }
    

    4.) 在您的页面 (Indx.aspx) 上允许 PageMethods,就像这样,

    <asp:ScriptManager runat="server" EnablePageMethods="true" />
    <div id="silverlightControlHost">
        <object data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%">
    

    祝你好运,
    Jim McCurdy,YinYangMoney.com

    【讨论】:

    • 非常感谢吉姆!我承认我希望有一个更清洁的解决方案,即没有 aspx/javascript 的东西。我发现最好远离浏览器附近的东西。但我很不情愿地开始意识到可能没有其他办法。顺便一提;您的解决方案是否适用于 Firefox 和 Chrome,以及 IE?
    • 我刚刚意识到您可以调用 WCF 服务而不是使用 PageMethod 方法;那也可以。您唯一不能做的就是从异步调用中获取已完成的事件,因为一旦您离开 Application_BeforeExit() 方法,Silverlight 应用程序就消失了。它应该可以在任何浏览器中运行;这就是为什么我列出了 2 个不同的 AttachEvent() 调用。
    • 再次感谢吉姆。很抱歉报告从 Application_BeforeExit() 对 wcf 服务的调用也永远不会到达服务器。我已经进行了一些研究,看来您的原始解决方案或类似方法是处理此问题的唯一方法。参见例如forums.silverlight.net/forums/t/20279.aspx。我的猜测是,一些未来的 Silverlight 版本会为此提供解决方案。毕竟“退出时保存”是一个非常需要的功能。
    • 嗨! PageMethodEventHandler 的程序集是什么?
    【解决方案2】:

    我认为在用户决定离开或浏览器终止后,您无法在服务器端执行任何操作。但是,您可以编写一些 JavaScript 来防止当前页面被卸载,您可以警告用户不要关闭它。

    其次,使用每两分钟左右计时的小型会话计时器。您的会话应该超时,但是当您的 Silverlight 应用程序在浏览器中打开并运行时,您应该通过编写一些 ping 方法来 ping 您的服务器,该方法将使您的会话每隔一分钟保持活动状态。

    因此,如果您的会话即将到期(在过去 60 秒内没有收到 ping),您的会话将被销毁,您可以在服务器的会话结束时编写一些清理代码。

    【讨论】:

    • Akash,感谢您的回复。我确实有一个像你描述的会话计时器,但是用户可能是邪恶的并刷新浏览器并重新登录 before 它启动。无论如何,有条不紊地进行清理会很好当这些事情发生时的时尚,而不是依赖会话计时器(keepalive)来整理。
    【解决方案3】:

    我对 MVC 应用程序有类似的要求。我所做的是使用 jQuery 订阅 unload 事件并对终止会话的控制器操作进行 ajax 调用:

    $(window).unload(function() {
      $.ajax({url: Url.Action("KillSession")});
    });
    
    public ActionResult KillSession()
    {
        Session.Abandon();
        return new HttpStatusCodeResult(System.Net.HttpStatusCode.NotModified);
    }
    

    【讨论】:

      猜你喜欢
      • 2011-03-28
      • 2011-09-30
      • 2019-12-03
      • 2011-03-15
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 2010-10-02
      • 1970-01-01
      相关资源
      最近更新 更多