2010-09-07 51 views
2

我的Silverlight 4應用程序通過wcf服務與服務器端保持聯繫。無論何時用戶刷新,瀏覽或終止瀏覽器,我應該對服務器端進行一些清理。如何檢測Silverlight 4的瀏覽器刷新?

我無法使用應用程序退出事件;我的wcf客戶端在它最終被調用之前就已經死了。我無法使用(新的SL4)FrameworkElement Unloaded事件;它在Silverlight應用程序關閉時不會被調用。

那麼,我該如何檢測瀏覽器刷新,newpage或關機及時來做我的清理?

回答

2

巴布,

當用戶從我的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)允許您PageMethods頁面(Indx.aspx)上,像這樣,

<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%"> 

祝你好運,
吉姆·麥柯迪,YinYangMoney.com

+0

非常感謝吉姆!我承認我希望有一個更清潔的解決方案,即沒有aspx/javascript的東西。我發現最好遠離瀏覽器 - 就像那樣。但我不情願地開始意識到可能沒有其他辦法。順便一提;您的解決方案是否可以在Firefox和Chrome以及IE中使用? – BaBu 2010-09-08 06:08:07

+0

我剛剛意識到您可以調用您的WCF服務,而不是使用PageMethod方法;那也可以工作。唯一不能做的是從異步調用中獲取完成的事件,因爲一旦離開Application_BeforeExit()方法,Silverlight應用就會消失。它應該可以在任何瀏覽器中使用;這就是爲什麼我列出了2個不同的AttachEvent()調用。 – 2010-09-09 00:22:48

+0

再次感謝吉姆。很抱歉,從Application_BeforeExit()調用wcf服務永遠不會到達服務器。我已經做了一些研究,似乎你的原始解決方案或類似的方法是解決這個問題的唯一方法。見例如http://forums.silverlight.net/forums/t/20279.aspx。我的猜測是,一些未來的Silverlight版本將爲此提供解決方案。畢竟'退出保存'是一個非常想要的功能。 – BaBu 2010-09-10 07:40:18

0

我不認爲你可以做任何服務器端後,用戶決定離開或瀏覽器終止。但是,您可以編寫一些JavaScript以防止卸載當前頁面,您可以在此警告用戶不要關閉它。

其次,使用一個小會話計時器,每兩分鐘左右滴答一次。您的會話應該超時,但是當您的Silverlight應用程序在瀏覽器中打開並運行時,您應該通過編寫一些ping方法來ping您的服務器,這會使會話每分鐘保持一次。

因此,如果您的會話過期(最近60秒未收到ping),您的會話將被銷燬,您可以在服務器的會話結束時寫入一些清理代碼。

+0

Akash,謝謝您的回覆。我的確有一個像你描述的會話計時器,但用戶可能是邪惡的,刷新瀏覽器並重新登錄。*無論如何,當這些事情發生時按順序進行清理會很好而不是依靠會話計時器(Keepalive)來整理。 – BaBu 2010-09-08 12:33:59

0

我有一個MVC應用程序類似的要求。我所做的是使用jQuery訂閱卸載事件,並對控制器操作進行ajax調用,以終止會話:

$(window).unload(function() { 
    $.ajax({url: Url.Action("KillSession")}); 
}); 

public ActionResult KillSession() 
{ 
    Session.Abandon(); 
    return new HttpStatusCodeResult(System.Net.HttpStatusCode.NotModified); 
}