How to check if asp session is valid? - asp.net

Im using outproc session that is managed by aspnet_state. Sometimes I get run time errors saying that the session is invalid. So I wanted to check if the session is valid for every request I make. But I couldn't find a proper way to do it like in this Question using Java.
Here is the code I'm using right now in the page_preinit event.It looks ugly but it works.
Try
Dim x = Session.Keys().Item(0)
Catch ex As Exception
Session.Clear()
End Try
Does any one knows a better approach?
Thanks

You could try checking the context object.
C#
if(Context.Session != null)
{
//Redirect to login page etc
}
VB (Used a C# to VB converter here..not sure if this is correct)
If Context.Session IsNot Nothing Then
    'Redirect to login page etc
End If
If you are using forms authentication and it is setup correctly, it should redirect for you. If you still need to be explicit, I would recommend placing this type of code in the Global.asax, or a base class that each of your pages could derive from, rather than adding it to every request.

Actually I solved the problem by checking the first element of the session( session.item(0) )
I put the code in try catch . if the there is an exception I just clear the session. This code is in a basepage for all my pages.
so in the preinit event my code look like this
Private Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Try
Dim x = Session.Keys().Item(0)
Catch ex As Exception
Session.Clear()
End Try
End Sub
It seems to be ugly but it does solve my problem.
Thanks everyone.

Just check the Session.Count instead of attempting to access the first item in an error handling block...

Related

What type of variable could I use for this?

What I am trying to do is simple in principle, but the lifecycle of ASP.NET pages is throwing a bucket of cold water into my day.
Here is the problem
We have implemented URL Redirection and I've inherited code that reads like this in Global.ASAX, on Sub Application_BeginRequest:
dv.Table = CommonFunctions.ConvertXmlFileToDataSet("/XmlData/WebAppFolders.xml").Tables("Application")
dv.RowFilter = "'" + fullOrigionalPath + "' LIKE '%'+ folder + '%'"
If dv.Count > 0 Then 'match on key to redirect
If fullOrigionalPath.EndsWith(dv(0)("folder") + "/") Then
Context.RewritePath(dv(0)("basePage"), True)
Else 'missing page in directory --> redirect
HttpContext.Current.Items("Raise404") = "true"
Response.Redirect("/" + dv(0)("folder"))
End If
Return
End If
Basically we are reading a large XML file that contains the URL redirects. That's working fine. The problem happens in the line...
HttpContext.Current.Items("Raise404") = "true"
In the context of Application_BeginRequest, the session object is not yet available, so I could not use it to store a flag which I named Raise404. Instead I had to resort to using the Items collection.
The problem occurs when the redirect takes place. The new page lifecycle destroys the Items array and overwrites it with a new empty one.
By the time I try to use my flag Raise404, it no longer exists on my page PreRender event.
To complicate matters we use master pages, and so I was asked to place the code that we want to execute in the master page
Ideally, if the Items array wasn't being destroyed, this code would work:
Private Sub Page_PreRender(sender As Object, e As System.EventArgs) Handles Me.PreRender
If HttpContext.Current.Items("Raise404") IsNot Nothing AndAlso HttpContext.Current.Items("Raise404").Equals("true") Then
Response.StatusCode = 404
HttpContext.Current.Items("Raise404") = Nothing
End If
End Sub
I am not sure what kind of variable I could use to store my flag and allow it to survive the redirect.
Any ideas?
Update: The problem is that the HTTP Handler servicing my request is System.Web.DefaultHTTPHandler, which does not implement IRequiresSessionState, and so when my request is being handled inside Global ASAX there is no session created. So, it seems like the solution will be to write a custom HTTPHandler that implements IRequiresSessionState, and use that for all my .aspx files. Even then, a session state is not created in Global.ASAX until PreRequestHandlerExecute is raised. So, putting it all together I think I need to write a custom HTTP Handler that implements IRequiresSessionState, and delay the redirection of the page until PreRequestHandlerExecute is raised where I will be able to store my flag into the Session state, and only after that, redirect my page.
Not very elegant, and I wonder if there will be any performance implications.
Have you considered using the query string for that?
Response.Redirect("/" & dv(0)("folder") & "?Raise404=true")
Then, in your Master Page, simply check QueryString("Raise404") and act accordingly.
The only drawback I can see is that a malicious client could deliberately add Raise404=true to the query string, which is not possible with your current solution. However, I do not see how that could do any harm.
As I suspected, my problem was directly tied to the fact that IIS 8 will avoid using an HTTPHandler that implements IRequiresSessionState if for performance reasons it detects that a session object is not needed, and so because the redirect code was happening during the Application_BeginRequest event, IIS was handling up to that point my requests using System.Web.DefaultHTTPHandler.
So, upon further research, I found this which was tremendous help:
IRequiresSessionState - how do I use it?
And I also documented myself on this article:
http://forums.iis.net/t/1094546.aspx
What solved my problem was to write a dummy HTTPHandler class. I added a new class to my app_code folder:
Imports System.Web
Public Class HTTPRequestHandler : Implements IHttpHandler, IRequiresSessionState
Private OriginalHandler As IHttpHandler
Public Sub New(handler As IHttpHandler)
Me.OriginalHandler = handler
End Sub
Public Sub ProcessRequest(context As HttpContext) Implements IHttpHandler.ProcessRequest
Throw New InvalidOperationException("HTTPRequestHandler cannot process requests.")
End Sub
Public ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return True
End Get
End Property
Public ReadOnly Property Handler() As IHttpHandler
Get
If Me.OriginalHandler IsNot Nothing Then
Return Me.OriginalHandler
End If
Return HttpContext.Current.Handler
End Get
End Property
End Class
Now, during Application_BeginRequest, session is not available but HttpContext.Current.Items is available. So, as the second article suggests, during PostMapRequestHandler I put a condition:
If HttpContext.Current.Items("Raise404") IsNot Nothing Then
Context.Handler = New MyNameSpace.HTTPRequestHandler(Context.Handler)
End If
And finally, that created the session object that I could finally use during PreRequestHandlerExecute:
HttpContext.Current.Session("Raise404") = "true"
Response.Redirect(HttpContext.Current.Items("Redirect"))
I will definitely not argue that this is not elegant, but it works and I can raise my 404 error during Page_PreRender on my master page.
I hope this may help others.
Cheers.

HttpContext.Current is Nothing after Transfer or Rewrite

I'm trying to rewrite a url like so:
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
If [some condition] Then
Dim sPath = [fix up path]
Context.RewritePath(sPath)
End If
End Sub
The new path is correctly invoked, but when it is, HttpContext.Current is Nothing, and this breaks my code. Server.Transfer and Server.TransferRequest have the same problem. Why is this, and what can I do to rewrite the request AND preserve the HttpContext?
Update: The same thing happens using the IIS Rewrite module.
It turned out that the particular code that I was testing after rewrite was running in a callback in an AsyncHandler, and as such was in a background thread, which never has a current HttpContext, and this was true before rewrite too. In this case, other things made me notice an unrelated bug for the first time.
But in case it helps anyone else, the takeaway is:
HttpContext.Current does not work in a background thread.

Clearing a session in ASP.NET

I'm a new developer, and I've been assigned the task of figuring out why our log out function is not working. I've tried every possible method I can find. Below is the log I've kept that includes the methods I've used.
Added a log out button to the CommonHeader.ascx form
Have tried numerous methods in the logout.aspx.vb form to get it to end or clear the session but none of them work.
a. ClearSession sub routine defined in the logout.aspx.vb form:
Session("Variable") = ""
FormsAuthentication.SignOut()
Session.RemoveAll()
Session.Abandon()
Session.Clear()
b. Also added this to the top of the Page_Load sub routine:
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache)
HttpContext.Current.Response.Cache.SetNoServerCaching()
HttpContext.Current.Response.Cache.SetNoStore()
c. Also changed the ClearSession sub routine to Session.Contents.Remove("Variable") from Session("Variable") = ""
None of these methods work. We use Siteminder, and I've been wondering if this is the root of the problem. I just can't find anything on clearing a Session that uses Siteminder. Also keep in mind this application is coded with Visual Studio 2003.
This is the code for the button I'm using in the ascx file:
athp:TopNavText Title="Log Out" NavigateUrl="logout.aspx" Target="_top"/
Then on the "logout.aspx" form I've tried just using one of the methods described above or a combination of each one. This is the code before I ever touch it:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ClearSession()
Response.Redirect("login.aspx")
End Sub
Public Sub ClearSession()
Session("Variable") = ""
End Sub
Finally figured out the solution, I originally did not define the domain upon deletion of the cookie which contained the siteminder session id. The code I used is as following:
Dim cookie3 As HttpCookie = New HttpCookie("SMSESSION", "NO")
cookie3.Expires = DateTime.Now.AddYears(-1)
cookie3.Domain = ".domain.com"
Response.Cookies.Add(cookie3)
Response.Redirect("login.aspx")
This question: formsauthentication-signout-does-not-log-the-user-out describes a problem with not clearing cookies even after calling FormsAuthentication.SignOut(). This sounds like your issue, they say it's a bug with .NET and as your using 1.1 this sounds distinctly possible.
HI friend please add the click event of the button in user control. And in the click event please add the following code and remove all the other code.
Session("Variable") = "";
look at this post
C# Clear Session
Whether its c sharp or vb the same rules still apply. You are calling session abandon then clear, but by the time you call clear the session should be gone anyway.
Clear keeps the session state along with the objects in it, so by calling it after abandon you could in fact be reinitializing a session for the user, but with cleared variables.
See this post for the order and proper way to kill the session and redirect to the login page if you have one
FormsAuthentication.SignOut() does not log the user out
The first thing to note is that, if you're using Forms Authentication, Session has absolutely nothing to do with whether or not a user is logged in.
Calling FormsAuthentication.SignOut will remove the forms-authentication ticket information from the cookie or the URL if CookiesSupported is false.
But it will have no effect on what is stored in Session.
UPDATE
Why do you think log out (FormsAuthentication.SignOut) is not working? What are you expecting to happen when you click on Sign Out, and what exactly is actually happening?
I'd get rid of all the code to clear Session and look at this. For example, look at the http traffic with a tool such as Fiddler: you should be able to see that the FormsAUthentication cookie is removed when you click on Log Out.

How do I detect if a request is a callback in the Global.asax?

I need to find a way to detect if a request is a callback when the Application_BeginRequest method is called.
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)<br />
Dim _isCallBack As Boolean = False
' Code to set _isCallBack is True or False Here
If Not _isCallBack Then
'... Some Code
End If
End Sub
I need to know what to replace "[Code to set _isCallBack is True or False Here]" with.
This may help you:
http://msdn.microsoft.com/en-us/magazine/cc163941.aspx
Search for the word __CALLBACKID:
To determine the callback mode, the ASP.NET runtime looks for a __CALLBACKID entry in the Request collection. If such an entry is found, the runtime concludes that a callback invocation is being made.
We needed to do this from within an app_code file where access to the Page.xxxx objects was not available. This is the code I ended up using:
If Not IsNothing(HttpContext.Current.Request("__CALLBACKID")) Then
'The request is a callback
Else
'The request is not a callback
End If
Maybe not the prettiest solution, but it does the job. We were using Array.IndexOf for a while, but it seems that sometimes that form parameter arrives back as lowercase parameter (not sure why or how), and Array.IndexOf is a case sensitive search.
Be careful looking for these kinds of __XXXX request keys. I remember reading somewhere that it's not a good idea to "shortcut" to these elements since their names could change in some future version of .net. Just keep that in mind!
I needed something similar and, following on Dean L's answer, figured .NET itself must know what to do. Looking in the HttpResponse.Redirect method with Reflector, you see code like this:
Page handler = Context.Handler as Page;
if (handler != null && handler.IsCallback)
{
//Code...
}
Seems to work fine in Global.asax.
Depends on the context of your question. I see you are talking about ASP.NET in the tags, using VB.NET. You can probably use:
If Not Request.IsPostback Then
' Your code here
End If

Dealing with Databinding Errors in ASP.net

This has been bugging me for a while but when I databind a control using with a Session variable as the parameter which has not been initialized there is an exception thrown which I can't seem to catch anywhere.
Ideally if the session varaible is not set I would just like to redirect but I can't seem to figure out where I need to check for this instance.
You must check the session object on page_init event.
Check it in your page load.
Sub Page_Load()
if Not Page.ispostback()
if session("Value") <>"" then
me.hiddenfield.value = Session("ValueName")
Else
Response.redirect("PAge.aspx")
End if
End if
End Sub
I tend to add some hidden fields as sessions eventually time out
then make the datasource use the hidden control for its reference

Resources