M
Mike Hofer
I really need some help, and I'd appreciate any that you folks can
provide.
The ASP.NET application in question uses version 1.1 of the .NET
Framework. All of the pages use a common base class (derived from
System.Web.UI.Page). So, for instance, my home page's inheritance chain
looks like this:
HomePage
Inherits WebPageBase
Now, in the event handler for the Load event of HomePage invokes a
method called LoadPage in WebPageBase. This method invokes a standard
set of overridable functions that ensure that specific things happen on
every web page in the application: it ensures that the user's
permissions are valid, that the default button is selected, that the
data is loaded, etc. It provides a consistent framework for handling
pages throughout the application.
Everything is peachy so far, right? Right. Thus far, everything has
been working beautifully.
The only problem that I really have is session timeouts. When the
user's session times out, my data is missing from the ASP.NET session
object, which causes all kinds of application wonkiness. Now, the
intelligent thing for me to do in those scenarios is to detect those
situations and redirect the user to the Logon page. However,
redirection is turning out to be a major pain in the neck.
To do this, I inserted code into the LoadPage method in the WebPagePage
class. This is the first method that is invoked by all web pages in
their Load event handlers. The idea was simple: at the end of the
LoadPage call, I stored the current date and time into the ViewState in
the web page. When the page was posted back to the server, I read it
back out and compared it to the current date and time. If the
difference between the two (in minutes) was greater than 29, then the
user's session has timed out. This should trigger a redirection to the
logon page. The nice thing about this technique is that it doesn't
require examining the Session object, whose data is volatile.
The method that ensures that the user is logged on, is as follows:
Public Function EnsureLoggedOn() As Boolean
Dim result As Boolean = True
If Not IsLogonPage And Not IsLogOffPage Then
If IsExpired Then
Navigator.ForceLogOn()
result = False
End If
End If
Return result
End Function
IsLogonPage and IsLogOffPage simply examine the URL of the current
page. IsExpired and LastPosted look like this:
Public ReadOnly Property IsExpired() As Boolean
Get
Dim ExpirationInterval As Integer = Settings.TimeoutMinutes
Dim result As Boolean
If LastPosted = #1/1/1900# Then
result = False
Else
result = DateDiff(DateInterval.Minute, LastPosted, Now) >
ExpirationInterval
End If
Return result
End Get
End Property
Protected Property LastPosted() As Date
Get
If Me.ViewState("LastPosted") Is Nothing Then
Return #1/1/1900#
Else
Return CDate(Me.ViewState("LastPosted"))
End If
End Get
Set(ByVal Value As Date)
Me.ViewState("LastPosted") = Value
End Set
End Property
For your viewing pleasure, Navigator.ForceLogon() looks like this:
Public Shared Sub ForceLogOn()
' This method forces the user to the Log On page, and terminates the
' current HTTP request. This method is used when the user's current
' request has expired and the user must be redirected to the logon
' page.
Dim server As HttpServerUtility = Cadmus.Internal.Environment.Server
Try
server.Transfer("~/forms/logonpage.aspx")
Catch e As Exception
Debug.WriteLine(e.ToString())
End Try
End Sub
However, getting the page to successfully redirect turned out to be a
problem. First I tried using Response.Redirect; it throws a
ThreadAbortException. No amount of exception handling in my code seems
to be able to capture this exception and handle it. It *always* crashes
the application.
A little research turned up Server.Transfer. So I tried that. It,
apparently has the same issue. So ixnay on atthay. Finally, I tried
Server.Execute. The result of that was that I had HTML from two
separate pages in the same browser window.
The problem seems to be that I am unable to get my application to
successfully redirect from one page to another without triggering a
ThreadAbortException or mixing the HTML from two separate pages into
one.
So I guess my question is this: How do you guys recommend handling
software-based session timeouts? My solution clearly isn't working.
What do you suggest?
provide.
The ASP.NET application in question uses version 1.1 of the .NET
Framework. All of the pages use a common base class (derived from
System.Web.UI.Page). So, for instance, my home page's inheritance chain
looks like this:
HomePage
Inherits WebPageBase
Now, in the event handler for the Load event of HomePage invokes a
method called LoadPage in WebPageBase. This method invokes a standard
set of overridable functions that ensure that specific things happen on
every web page in the application: it ensures that the user's
permissions are valid, that the default button is selected, that the
data is loaded, etc. It provides a consistent framework for handling
pages throughout the application.
Everything is peachy so far, right? Right. Thus far, everything has
been working beautifully.
The only problem that I really have is session timeouts. When the
user's session times out, my data is missing from the ASP.NET session
object, which causes all kinds of application wonkiness. Now, the
intelligent thing for me to do in those scenarios is to detect those
situations and redirect the user to the Logon page. However,
redirection is turning out to be a major pain in the neck.
To do this, I inserted code into the LoadPage method in the WebPagePage
class. This is the first method that is invoked by all web pages in
their Load event handlers. The idea was simple: at the end of the
LoadPage call, I stored the current date and time into the ViewState in
the web page. When the page was posted back to the server, I read it
back out and compared it to the current date and time. If the
difference between the two (in minutes) was greater than 29, then the
user's session has timed out. This should trigger a redirection to the
logon page. The nice thing about this technique is that it doesn't
require examining the Session object, whose data is volatile.
The method that ensures that the user is logged on, is as follows:
Public Function EnsureLoggedOn() As Boolean
Dim result As Boolean = True
If Not IsLogonPage And Not IsLogOffPage Then
If IsExpired Then
Navigator.ForceLogOn()
result = False
End If
End If
Return result
End Function
IsLogonPage and IsLogOffPage simply examine the URL of the current
page. IsExpired and LastPosted look like this:
Public ReadOnly Property IsExpired() As Boolean
Get
Dim ExpirationInterval As Integer = Settings.TimeoutMinutes
Dim result As Boolean
If LastPosted = #1/1/1900# Then
result = False
Else
result = DateDiff(DateInterval.Minute, LastPosted, Now) >
ExpirationInterval
End If
Return result
End Get
End Property
Protected Property LastPosted() As Date
Get
If Me.ViewState("LastPosted") Is Nothing Then
Return #1/1/1900#
Else
Return CDate(Me.ViewState("LastPosted"))
End If
End Get
Set(ByVal Value As Date)
Me.ViewState("LastPosted") = Value
End Set
End Property
For your viewing pleasure, Navigator.ForceLogon() looks like this:
Public Shared Sub ForceLogOn()
' This method forces the user to the Log On page, and terminates the
' current HTTP request. This method is used when the user's current
' request has expired and the user must be redirected to the logon
' page.
Dim server As HttpServerUtility = Cadmus.Internal.Environment.Server
Try
server.Transfer("~/forms/logonpage.aspx")
Catch e As Exception
Debug.WriteLine(e.ToString())
End Try
End Sub
However, getting the page to successfully redirect turned out to be a
problem. First I tried using Response.Redirect; it throws a
ThreadAbortException. No amount of exception handling in my code seems
to be able to capture this exception and handle it. It *always* crashes
the application.
A little research turned up Server.Transfer. So I tried that. It,
apparently has the same issue. So ixnay on atthay. Finally, I tried
Server.Execute. The result of that was that I had HTML from two
separate pages in the same browser window.
The problem seems to be that I am unable to get my application to
successfully redirect from one page to another without triggering a
ThreadAbortException or mixing the HTML from two separate pages into
one.
So I guess my question is this: How do you guys recommend handling
software-based session timeouts? My solution clearly isn't working.
What do you suggest?