Solved

Global.asax problem - session_start fires twice

Posted on 2004-09-22
44
3,702 Views
Last Modified: 2008-01-09
This is a second attempt to get a resolution to this problem with some new information.

I have a .NET application that has the following code in the Session_Start event:

Application("SessCount") += 1

Now when I display Application("SessCount") in an aspx page it sometimes (not always!) increments by 2 after starting the application. If I put a break point on 'Application("SessCount") += 1' it stops twice. The event is being fired twice.

I can't seem to resolve this problem. Can anyone suggest how I can track down this problem?

I'm using Visual Studio and .NET Framework 1.1.
0
Comment
Question by:ravl
  • 23
  • 14
  • 7
44 Comments
 
LVL 20

Expert Comment

by:ihenry
ID: 12121584
Do you call Session.Abandon somewhere? or do you have any page with frame in the project?
0
 
LVL 1

Author Comment

by:ravl
ID: 12122095
I don't call session.Abandon, but the application variable is being displayed in the main page of a frames structure, yes.
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12122706
you are dealing with a frame set are'nt you
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12122725
have you noticed that if you allow the seesion to expire while you page is open and when you refresh to start a new session you obtain the correct value ie 1 instead of 2
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12122815
its an unfortunate traite of the session object that dealing with frames when instantiating a new session is a pain

the first time you load the page each frame fires the session_start subroutine

I cant get around it but read this for more of an insight

http://www.google.co.uk/search?q=cache:0hNZ_wUZttAJ:msdn.microsoft.com/library/en-us/dnaspp/html/ASPNetSessionState.asp+asp.net+session+counter&hl=en

0
 
LVL 20

Expert Comment

by:ihenry
ID: 12123520

Normally when user make a request to a page that contains a frameset it will first send the request to the web server and then the browser will send individual request from each page in frames. This means, if you have a page with frameset that contains 2 frames, the web server will actually receive three requests from the browser and each request carries the same session id. This occurs when the three pages have aspx extension. And if any of the page has extension other than aspx you'll get different behaviour.

Personally I don't really like working with frames and when I need to maintain session variables across pages in frames that would be my last option. If you can elaborate on what you are trying to achieve there're might be a workaround.
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12123702

session variables are the same with or without frames. A session is dependant on the instance of your browser not your frame. I am dealing with a 3 frame htm page each frame uses aspx pages, my site is built on session vars with an SQL server back end.

The problem is despite each frame sharing the same session ID when the sesion is instantiated ie by declaring a variable the session_start event is still fired by each frame the first time the framset loads, so if you have a counter in the session_start rountine naturally you will get a false idea of the number of users. In turn if you decide to divide the counter by three you will be wrong again. This is because when the session timesout or is abandoned starting a new session while the browser window remains open, the session_start event is only fired once .... i have spent as long time debugging and testing this issue to no true resolution, the only reall answer i have found is "don't use frames" which is not an option for me

If i find a solution i will post it here
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12123900

Hi Andre412, just out of curiousity, have you tried using html page as frameset and aspx in frames? during the first request do all the pages have the same session id? :o)
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12123946
indeed i am using an html framest page of aspx frames

indeed they do, all requests they have the same seesion ID
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12124171
mm..that's strange.. I use an htm file as frameset and I get different session id for each frame, but ONLY on the very first request. Subsequent request they are all having the same session id. Any reason why this isn't happen to you?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12124336
Andre412, I'm still confused with the two statements below

>> ...despite each frame sharing the same session ID...
>> ...the session_start event is still fired by each frame the first time the framset loads...

and

>> ...indeed they do, all requests they have the same seesion ID...

if indeed frameset and its frames have the same session id for all requests then why session_start event is fired more than once when the frameset loads at the first time?
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12124524

what i mean is, each frame fires the session_start event the first time the frameset loads and they all share the same sessionID

[quote]
>if indeed frameset and its frames have the same session id for all requests then why session_start event is fired more than >once when the frameset loads at the first time?[/quote]

I dont know why it is fired more than once, perhaps something to do with the headers or the httprequest, its definately something low level, something to do with updating the session object in time before the next request is processed

I think this is an underlying issue yet to be curred with .NET, i dont know how to intercept the session
_start call, iv tried everything from checking session ID values to setting session vars all sorts of simple and complex solutions and none of them work. But i havnt given up yet

0
 
LVL 4

Expert Comment

by:Andre412
ID: 12124575
you may experience diff session ids if in your session_start you dont set a session var

every request is given an id and every request will have a diff id until you set a session var
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12124736
>> you may experience diff session ids if in your session_start you dont set a session var...
That's not quite true if you define Session_OnStart event in global.asax, asp.net will store session state even if there's no session variable defined in the application. It's clearly described in the article you posted above :o)
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12124755
my point is on each subsequent request a new session id will be provided
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12124786
a quote from the article

Figure 3. A new session ID is generated for each request in applications that do not store data in the session dictionary.

in other words until you do something like session("somesessionvar")="on" then your gona be given a dif id on each request
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12124805
be back tomorrow must go training :-( i hate the bit before but always feel better after :-)
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12124867
I'm referring to this paragraph,

What about the Session_OnStart event? Is it fired for each request too? If the application defines a Session_OnStart handler, then the session state is always saved, even if empty. As a result, the session ID remains constant for all requests after the first.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12124895

happy training :o)  see you again tommorow here..
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12125088

Btw, when you come back here tommorow try to google with "Understanding session state modes + FAQ" and read the answer for question "I have a frameset page which has an HTM extension, and I found out each frame it contains display a different session id on the first request. Why?"

and you may find this thread is interesting
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/ASP_DOT_NET/Q_21125539.html


Have a nice day! :o)
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12131048

hello ravl, any update to the problem?
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12131223
morning

ok i think this is what i think is happening.

1] client loads homepage, homepage is an html framset of 3 pages, remember .html files dont run the session start event
2] from the single request has spawned 3 request for 3 .aspx pages or in your case 2
3] this is all under one request dont forget
4] ASP.NET retrieves request session id from http cookie (ASP.NET_SessionId) that is attached in http request of the client browser. ASP.NET then looks for the same session id in the configured state provider storage (Session dictionary, SQL Server or NT state service). If one does not exist ASP.NET generates a new session id and raises the Session_OnStart event.

heres the tricky bit, because the request hasnt finished processing nothing will be written in the state provider storage, it is only written once the request is complete, thats why on each frame load the session_start is fired

we need to somehow work around this issue or intercept and handle the triple (double in your case) call to session_start before it gets there.
Im actually considering a redirection .aspx page who's job is purely to obtain a single sessionid for the duration of the session and use this as the homepage, but thats messy and i dont really want to.

0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 1

Author Comment

by:ravl
ID: 12131577
Jees! That started some discussion! Thanks a lot guys.

So, it's 'cos the page is part of a frameset. Yes, I can indeed verify that if I make the page displaying the counter the start page it all works correctly. As soon as as I make it the main page in the frameset the numbers go up by twos. Though, curiously, sometimes it does go up by one's!

At least I know the answer now. I am actually trying to count individual visits to the site of course. I can't dump the frames without a lot of re-work, so I'm stuck. I did think of the redirection option you mentioned in your last comment, Andre412, but as you say - messy.

I guess I'll just have to rely on the site stats.

Pity the MCSD course doesn't mention this problem in passing! How many hours of research do you think it would take to track this down from docmentation?

How about I split the points between the two of you - happy with that?
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12131609
I think i may have a solution, just give me about 35 minutes to make sure
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12131696
ok guys heres the solution

right basically every frame starts the session_start event we already know this, the trick is to only record one of the

so we are going to use the session.isnewsession property of the session object

it basically identifies if that particular request started the stream to the client and only one frame will have this property set to true

so in your global asaz file do this, and it should solve your problem,

Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
           'initialise session only for one frame
            If Session.IsNewSession Then
                Application.Lock()
                Application("ActiveUsers") = CInt(Application("ActiveUsers")) + 1
                Application.UnLock()
            End If
End Sub

your end session can look like this

Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
        Application.Lock()
        Application("ActiveUsers") = CInt(Application("ActiveUsers")) - 1
        Application.UnLock()
end sub

:-) do you know how long it has taken me to solve this problem..... only to find out it was a simple solution.... I hate that !
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12131721
wait a minute ... this needs tweeking
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12131858

Andre412, I don't believe that will work with frames. Each page will trigger Session_Start event and each has Session.IsNewSession is equal to true.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12131881

ravl, which session state mode you are using?
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12132032
I know

That is why i said "wait a minute this needs tweeking"

I am working on a set of rules that can be applied in the session_start and end events

Just need a little more time
0
 
LVL 1

Author Comment

by:ravl
ID: 12132771
I'm using In Proc
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12133278
ok guys I think i have cracked it

let me do a few more tests just to be sure this time :-)
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12144262

Andre412, any progress with your testing? :o)
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12144493
Yes

I have managed to get the counter to increase only once regardless of the number of frames but im still working on handling session time out's and session.abandon

Im talking to a chap called Dr Nitin Paranjape I read his article here

http://www.expresscomputeronline.com/20031215/techspace01.shtml

I have yet to recieve a response. Rest assured i will find a solution to this because it affects my companies website. In fact i cannot rebuild the solution and make it live until this is solved because the code has now changed so much It would take ages to back track.

0
 
LVL 20

Expert Comment

by:ihenry
ID: 12144703

ravl, what's the counter exactly for? are you counting based on hits regardless of who, where or how many browsers have been opened in a same client machine? There're many factors to consider if you want to build a serious visitor tracker and relying on a single application variable definitely is not just enough.
0
 
LVL 1

Author Comment

by:ravl
ID: 12148694
Hi ihenry - I just want to count visitors to the site. I realise that this is a simplistic solution and not necessarily accurate, but I don't need that accuracy - just a ball park feel for visitor numbers. It's just that the frame problem produces such an obvious error I wanted to fix it. It seems to me that assuming a new session is a new visit is reasonable, short of reading the mind of the user.

Actually, what I'm doing is incrementing a counter in a database. The counter is displayed on the home page which is part of a frame set. I call a stored proc in the session_start to bump the counter. Using the application var was just a ploy to simplify debugging and eliminate the stored proc as the cause of the problem.

Andre412 seems determined to resolve a way to do this - so I'm waiting with baited breath!
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12159748
Quick update guys

Im still in talks with this Dr chap, i have several projects on the go and tend to juggle my time between them all.

I think i will either have the solution soon or declare this as unsolvable.
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12215632
Further update

Dr whatever his name is, isnt really as knowledgable as i had previously thought. He pretty much gave up before starting, if not he suggested rediculous solutions that would either not work or hinder the performance of the site. Im actually wondering how this guy got his doctorate

Ok i am  testing a solution just now, however over the weekend the numbers started to drfit negative, i have made some minor adjustments this morning and wil monitor the count again over the next day or so. Fingers crossed.
0
 
LVL 4

Accepted Solution

by:
Andre412 earned 250 total points
ID: 12217429
Ok i have been keeping my eyeon the site for most of the day and there have been no problems
I will be testing this this week but i feel you can use the code and test along side.

copy and paste this code into your global.aspx file, amending your existing routines, ie add any other code you may wish to run, be aware of any (exit sub)'s.
Any bugs let me know. I think there is one issue concerning a refresh post this session timeout but im not sure its still there. Like i said i will be testing this most of this week

keep me posted of any bugs you can find.

Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
          ' Set our user count to 0 when we start the server
        Application("ActiveUsers") = 0
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
        Try
            'ok you must keep your main frameset source pages constant otherwise this
            'wont work. In the same order of frameset declaration in your html or
            'html framset page we start with a case if,
            'each elseif is for each frame so if you have two frames you only need one elseif
            'so frame 1's target = menu.aspx
            'frame 2's target = sidebar.aspx
            'frame 3's target = default.aspx
            If LCase(Request.Url.ToString).IndexOf("menu.aspx") > 0 Then
                'ensure this is a new session request (handles second load of website in another browser)
                If Session.IsNewSession Then NewSession() : Exit Sub
                'frame2 target = sidebar.aspx
            ElseIf LCase(Request.Url.ToString).IndexOf("sidebar.aspx") > 0 Then
                If Request.Cookies("SessionID").Value = Session.SessionID Then
                    If Session.IsNewSession Then NewSession() : Exit Sub
                End If
                'frame3 = test3.aspx
            ElseIf LCase(Request.Url.ToString).IndexOf("default.aspx") > 0 Then
                If Request.Cookies("SessionID").Value = Session.SessionID Then
                    If Session.IsNewSession Then NewSession() : Exit Sub
                End If
            End If
            'Context.Response.Write("bugga boo " & Application("ActiveUsers"))
            Session.Abandon()
        Catch ex As Exception
            Session.Abandon()
        End Try
End Sub
          
Sub NewSession()
        'monitor number of clients on the site and instantiate a session
        Application.Lock()
        Application("ActiveUsers") = CInt(Application("ActiveUsers")) + 1
        Application.UnLock()
        Session("SessionID") = Session.SessionID
        Response.Cookies("SessionID").Value = Session.SessionID
End Sub
   
Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
        'Session tracking
        Application.Lock()
        Application("ActiveUsers") = CInt(Application("ActiveUsers")) - 1
        Application.UnLock()
End Sub
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12217732
let me explain in more detail what session_start does

first of all it checks for frame source page
Secondly it checks for a new session request
thirdly will start a new session providing the request pass's all logical questions

rules are
only start  a new session if
a)the home page is being loaded for the first time
b)the session has timed out and they begin to navigate the site again
c)session_abandon is called

We use three objects to help us do this
1) the frames source page (constant)
2) isnewsession request (boolean and only true if its a new session request)
3) a cookie which we will be placing sessionID into on a sessino start, we only use the cookie to test for the other frames right to start a session.

session behaviour:
All frames gain a different sessionID every time a request is made, until such time as you instantiate a session variable from any frame, at this point all frames share the same sessionID, another thing to bare in mind is that even when the session times out, the sessionID remains in the header of the html page and is posted back to the server on the next request ie even when a session times out, on a refresh the same sessionID is used again for the new session, interesting i know thats where the cookie comes in.
So this means we can satisfy all rules using our objects, and its all done in session_start
if the rules are not adheard to we dont want to start a new session hence session_abandon, its odd this is placed in the sess_start but it seems to be working well.

Hope this is clear enough
0
 
LVL 1

Author Comment

by:ravl
ID: 12221726
OK Andre412, I'll have a look at this this week. Thanks.
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12235307
Im pleased to say i think i cracked it.

Having kept a close eye on this for the past few days i believe that this has solved the problem, its more of an advanced work around really.

Anyway this will be my final post on this topic unless anyone has problems with my explanation in which case i will be happy to explain the theory behind the code.

So ravl, i believe we have an accurate counter for our websites now :-) i have spent quite a while on this problem and now believe we are the only ones in the commercial market to have solved it.

Thanks for being so patient

Best Regards

André
0
 
LVL 1

Author Comment

by:ravl
ID: 12272583
Sorry, Andre - couldn't get back to this issue last week - will definitely look at it this week.
0
 
LVL 1

Author Comment

by:ravl
ID: 12294100
Congratulations Andre, I can't fault your solution so far. Seems to work well. So, I guess you really earned these points. Thanks for all your work.

Regards Rob
0
 
LVL 4

Expert Comment

by:Andre412
ID: 12298634
I find it works perfectly, with no issues.

jobs a winner

cheers

André :-0
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Just a quick little trick I learned recently.  Now that I'm using jQuery with abandon in my asp.net applications, I have grown tired of the following syntax:      (CODE) I suppose it just offends my sense of decency to put inline VBScript on a…
This article discusses the ASP.NET AJAX ModalPopupExtender control. In this article we will show how to use the ModalPopupExtender control, how to display/show/call the ASP.NET AJAX ModalPopupExtender control from javascript, how to show/display/cal…
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now