rogerdeuce rogerdeuce - 15 days ago 5
Vb.net Question

Maintaining page number in DropDownList after postback to refresh server timeout

I'm using .Net, VB and webforms. I have a timer that pops up to allow the user to refresh their connection before the session expires. Three of the pages in the app use the exact same style

DropDownList
in order to control the content that is being displayed.

When the user clicks "ok" to refresh a page that contains a
DropDownList
, the user gets an error that the
DropDownList
can only have one item selected.

How do I make the page render after postback in the same state that it was in pre-popup?



Protected Sub ddlPages_SelectedIndexChanged1(ByVal sender As Object, ByVal e As System.EventArgs)
'switch to page selected in pager
Dim gvrPager As GridViewRow = gvSelectEvents.BottomPagerRow
Dim ddlPages As DropDownList = DirectCast(gvrPager.Cells(0).FindControl("ddlPages"), DropDownList)

gvSelectEvents.PageIndex = ddlPages.SelectedIndex

'populate your grid
gvSelectEvents.DataBind()
End Sub

<%@ Control Language="VB" AutoEventWireup="false" CodeFile="TimeOutControl.ascx.vb"
Inherits="UserControls_TimeOutControl" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>

<script type="text/javascript">
var DoLogout = 1;
var WarnMills;
var TimeoutMills;
var WarnDurationMills;
var RedirectURL;
var _timeLeft;

function StartTimeout(TimeoutValue, WarnValue, WarnDuration, URLValue) {
TimeoutMills = TimeoutValue;
WarnMills = WarnValue;
WarnDurationMills = WarnDuration;
RedirectURL = URLValue;
setTimeout('UserTimeout()', TimeoutMills);
setTimeout('WarnTimeout()', WarnMills);
}

function UserTimeout() {
if (DoLogout == 1) {
top.location.href = RedirectURL;
}
else {
DoLogout = 1;
setTimeout('UserTimeout()', TimeoutMills);
setTimeout('WarnTimeout()', WarnMills);
}
}

function WarnTimeout() {
_timeLeft = (WarnDurationMills / 1000);
updateCountDown();
$find('mdlSessionTimeout').show();
}

function updateCountDown() {
var min = Math.floor(_timeLeft / 60);
var sec = _timeLeft % 60;
if (sec < 10)
sec = "0" + sec;

document.getElementById("CountDownHolder").innerHTML = min + ":" + sec;

if (_timeLeft > 0) {
_timeLeft--;
setTimeout('updateCountDown()', 1000);
}
}

function PreserveSession() {
DoLogout = 0;
__doPostBack('btnPreserveSession', '');
}
</script>

<PagerTemplate>
<asp:ImageButton ID="ImageButton1" runat="server" ImageUrl="images/firstpage.gif"
CommandArgument="First" CommandName="Page" />
<asp:ImageButton ID="ImageButton2" runat="server" ImageUrl="images/prevpage.gif"
CommandArgument="Prev" CommandName="Page" />
<span style="color: White;">Page</span>
<asp:DropDownList ID="ddlPages" runat="server" AutoPostBack="True" OnSelectedIndexChanged="ddlPages_SelectedIndexChanged1">
</asp:DropDownList>
<span style="color: White;">of</span>
<asp:Label ID="lblPageCount" runat="server" ForeColor="White"></asp:Label>
<asp:ImageButton ID="ImageButton3" runat="server" ImageUrl="images/nextpage.gif"
CommandArgument="Next" CommandName="Page" />
<asp:ImageButton ID="ImageButton4" runat="server" ImageUrl="images/lastpage.gif"
CommandArgument="Last" CommandName="Page" />
</PagerTemplate>




Answer

You don't need to refresh the page to keep the session active. Instead, you can just use AJAX to call a method in an .asmx file which has EnableSession:=True.

An example of the code for that:

Imports System.Web.Services
Imports System.Web.Services.Protocols
Imports System.ComponentModel

' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ToolboxItem(False)> _
Public Class SessionKeepAlive
    Inherits System.Web.Services.WebService

    ' this function is to called every 19 minutes from the Master page
    ' to keep the session alive.
    <WebMethod(EnableSession:=True)> _
    <Script.Services.ScriptMethod(UseHttpGet:=True)> _
    Public Function Check() As String
        If HttpContext.Current.Session("username") Is Nothing Then
            Return "expired"
        Else
            Return "ok"
        End If
    End Function

End Class

And if you were using an <asp:ScriptManager>, the JavaScript for the AJAX could look like:

<script type="text/javascript">                                                                               
    //<![CDATA[                                                                                           
    var keepAlive = function() {                                                                          
        Sys.Net.WebServiceProxy.invoke("SessionKeepAlive.asmx", "Check", true, {}, SessionKeepAlive_Callback);
    }                                                                                                     

    function SessionKeepAlive_Callback(result, eventArgs) {                                               
        if (result != 'ok') {                                                                         
            alert('Your session has timed out.\nPlease log in again.');                           
            window.location = 'login.aspx';                                                       
        };                                                                                            
    }                                                                                                     
    // Set 19 minute .NET session keep alive timer...                                                     
    window.setInterval(keepAlive, 19 * 60 * 1000);                                                        
    //]]>                                                                                                 
</script>                                                                                                     

You might choose a different way of calling the method in the web service, e.g. by using jQuery.