Redirect from Global.asax - c#

HttpContext.Current.Response.Redirect("~/default.aspx");
When i use this code in session_end in global.asax
error to me:
Object reference not set to an instance of an object.
why?!

Session_end is not an event that gets called by the user of your application, it's something that gets called by the server when a session times out. So when you try to access HttpContext, it is null because there is no HttpContext to access (no user who is currently performing some kind of interaction with your site).
Your attempt to redirect a non-existing HttpContext will always fail no matter what you do.

When the event SessionEnd is raised the Request and then the Response are null.
HttpContext.Current.Response //this is null
This is by design: Session ends not during a request but when the session timeout
It usually (default config) happens 20 minutes after the last request.
Since there is no request there is also no response.
You need to understand better how Asp.net Session State works
Anyway if you want to redirect the user to a page if the Session is expired you can check for one of your variables stored on session:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["YOUR_VAR_NAME"]==null)
{
Response.Redirect("~/default.aspx");
}
}

Session_End is fired internally by the server, based on an internal timer. Thus, there is no HttpRequest associted when that happens. That is why Response.Redirect or Server.Transferdoes not make sense and will not work.
I hope the above information will be helpful

Related

How to trigger a method when session timeout is completed?

I've a method which logs user activities in the database, I need to capture the logout activity but in our website there's no logout functionality so i want to trigger this user activity method when the session timeout occurs or when the browser is closed. I've tried calling this method from Session end method, but it dint work
you can handle on Session_End in Global.asax file
protected void Session_End(Object sender, EventArgs e)
{
// Remove user from HashTable
}
this method only call when Session Is get Timeout
only way to track the browser closing is Js
and for this purpose This link should help you

Session is null in AcquireRequestState when loading virtual directory name in browser, but not null when loading Default.aspx

I have an ASP.NET 4.0 WebForms application. I need to access HttpContext.Current.Session and set a value in the AcquireRequestState event (or an event after it) in Global.asax, and I've found a peculiar behavior.
Let's say I have a virtual directory in IIS (version 7 in my case) called Foo. In that I have Default.aspx as the home page. A sample Global.asax file is below:
<%# Application Language="C#" %>
<script runat="server">
void Application_AcquireRequestState(object sender, EventArgs e)
{
HttpContext.Current.Session["key"] = "value";
}
</script>
When I visit http://localhost/Foo/Default.aspx in my browser, it works just fine. When I visit http://localhost/Foo/ I get a NullReferenceException where I set the value on the session. The only change is the URL in the browser. They end up hitting the same page, but the framework behaves differently based on whether or not the URL contains just a folder name, or if it contains an aspx file.
Checking if (HttpContext.Current.Session != null) is not an option for me, because I need to set a value on the session with every request, which is non negotiable.
Is there a config setting in IIS that I'm missing, or is this a bug/forgotten feature?
An answer for another question hinted at the fact IIS does not load the session for every kind of request, for example style sheets don't need a session. Maybe this behavior is happening because IIS can't tell ahead of time if that folder name will result in executing an aspx file or if it will deliver a static HTML file?
Update: I even tried re-ordering the default documents that IIS looks for so that "default.aspx" was at the top of the list, e.g.
default.aspx
Default.asp
Default.htm
...
And I am still getting the same problem.
Update:
The event handler is only getting fired once because it is resulting in a NullReferenceException. I've done some additional reading and I know ASP.NET triggers these events for every request, even for CSS or JavaScript files. Additionally, the session object is not loaded for static files because there is not code that accesses the session, thus no need to load the object. Even so, the very first request is the request for the web page, which will need the session, and the session is null.
#DmytroShevchenko asked:
First add a guard check if (HttpContext.Current.Session != null) so that there is no NullReferenceException thrown. Then try to see, maybe the event will be fired a second time, with a session available.
Modified code:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
I set a break point at the if statement. I saw this event fire 4 times:
session is null
session is null
session not null
session is null
When continuing to step through the code each time, only when it started executing Default.aspx and its code-behind did I have a session available. I actually had the web page open in Firefox and was monitoring the network requests. The first request was for http://localhost/Foo/.
Next I set a breakpoint in Application_BeginRequest as well and got the following events:
BeginRequest
AcquireRequestState
BeginRequest
AcquireRequestState
BeginRequest
AcquireRequestState (session is not null)
Execute Default.aspx (/Foo returns a response to the browser)
BeginRequest
AcquireRequestState (session is null again)
At #9 the AJAX request in the browser to http://localhost:54859/8fad4e71e57a4caebe1c6ed7af6f583a/arterySignalR/poll?transport=longPolling&connectionToken=...&messageId=...&requestUrl=http%3A%2F%2Flocalhost%2FFoo%2F&browserName=Firefox&userAgent=Mozilla%2F5.0+(Windows+NT+6.1%3B+WOW64%3B+rv%3A41.0)+Gecko%2F20100101+Firefox%2F41.0&tid=4&_=1445346977956 is hanging waiting for a response.
I found a discussion about the differences between serving a page by its explicit URL and serving a default document.
With MVC and WebAPI, a new HttpModule was introduced: ExtensionlessUrlHandler. I believe that your event firing multiple times (and only once with session being available) may be caused by this module or other (re)routing logic of ASP.NET that actually redirects ASP.NET to handle Default.aspx.
Also, as you yourself mentioned, these events can be triggered for static file requests.
The bottom line is, you should not rely on session being available every time your event is fired. But it is safe to assume that you can access session at least once when serving an ASP.NET page. Hence, this is how your code should look like:
void Application_AcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Session != null)
{
HttpContext.Current.Session["key"] = "value";
}
}
What is happening is that certain events that occur prior to transferring the request to the page, trigger this event. Similarly, this event can be raised by other than ASPX pages. I think you need to do a few things:
set AutoEventWireUp to false in your page's code (in default.aspx). It seems odd and unrelated, but apparently this can resolve your issue.
check for null. Really. Because from all events, you are only interested in those events that originated from an ASPX page (or similar) that actually have a session state. Since every true request from a user always creates a session, you can simply filter for these without worrying that you miss certain events. As you have seen, at every cycle, there is always at least one event hit that has a set Session.
use PostAcquireRequestState, it is the more natural thing to use (or use PreRequestHandlerExecute), because on that event, all state is guaranteed to be set and filled.
I think your request url is not contain ".aspx", right?
The IIS7+ version has the config whitch will not use the "SessionStateModule" when it think the request handler is not managedHandler
So the solution is easy
Find your web.config, then add the property
<modules runAllManagedModulesForAllRequests="true">
....
</modules>
runAllManagedModulesForAllRequests="true" tell asp.net use all modules anyway
hope helpfull
When the resource has compilation error then the session will be null even in Application_PostAcquireRequestState

SessionID changing at every page call

I'm accessing the SessionID using this code in my class:
HttpContext.Current.Session.SessionID;
however I find that SessionID changes at every page postback, this happens in a short time, so the current session should not expire already. I supposed that the SessionID to remain the same for the whole time until expired.
When using cookie-based session state, ASP.NET does not allocate
storage for session data until the Session object is used. As a
result, a new session ID is generated for each page request until the
session object is accessed. If your application requires a static
session ID for the entire session, you can either implement the
Session_Start method in the application's Global.asax file and store
data in the Session object to fix the session ID, or you can use code
in another part of your application to explicitly store data in the
Session object.
like
protected void Session_Start(Object sender, EventArgs e)
{
Session["init"] = 0;
}
You should Use the Session_Start method in the application Global.asax file. Below Link may help you
ASP.NET: Session.SessionID changes between requests

ASP.NET MVC4 - Session_End - How can I get the currently logged on user's name in Session_End of Global.asax?

My issue is that once Session_End executes in my Global.asax, the HttpContext.Current object no longer exists- probably as expected, I would imagine. So, what I'm trying to do is once the session ends, update my Logins table for the user currently logged in and set their LoggedIn status to False. Here's my Session_End:
protected void Session_End(object sender, EventArgs e)
{
Helpers.OperationContext.UpdateIndividualLogin();
}
As you can probably guess, I can try to pass in:
System.Web.HttpContext.Current.User.Identity.Name
But this object no longer exists because I can only imagine that it's already been disposed of. So, is there any way I can grab the currently (or previously current) user's name?
You can do this by storing the information you want (in this case the user name) in Session. You can store it when the user is authenticated.

ASP.NET sessionID will not update

I click on refresh button which should restart session:
protected void btnRefresh_Click(object sender, EventArgs e)
{
HttpContext.Current.Session.Abandon();
HttpCookie mycookie = new HttpCookie("ASP.NET_SessionId");
mycookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(mycookie);
LblSessionID.Text = HttpContext.Current.Session.SessionID+
" test btnRefresh_Click";
LblIsNewSession.Text = Session.IsNewSession.ToString();
}
But when the button is clicked, the SessionID value in LblSessionID still displays the old value but another label LblIsNewSession will show it as true for IsNewSession. The LblSessionID will then reflect the actual SessionID value when I use asp.net control (like dropdown) that has autopostback="true" and from there SessionID sticks around.
I do use global.asax
Any idea why LblSessionID isn't behaving as it should and is waiting for next postback to start reflecting actual value?
When I launch the web application, the problem is the same - LblSessionID show different value and then change after first postback and stays the same from there.
That's the way it works - If you Abandon the session it won't reflect that until the next Request. It makes sense if you think about it...
Say you have a user that accesses your site and gets a Session ID of 123 (not reflective of an actual value, I know). When you click your button to get a new Session ID, the user's request is from the old Session, and that is the value that is reflected during that Request. Once the session is reset (or abandoned or whatever), the user gets a new Session ID of 321 and subsequent Request's will then reflect that new session ID.
SessionId is not reliable unless you actually store something (anything) in the session.
try
Session.RemoveAll();
Session.Clear();
It is not your code, it is a documented behavior:
"The Abandon method sets a flag in the session state object that indicates that the session state should be abandoned. The flag is examined at the end of the page request. Therefore, the user can still use session objects after you call the Abandon method. As soon as the page processing is completed, the session is removed."
(source: http://support.microsoft.com/kb/899918)
The Abandon() method flags the session collection for clearing at the end of the request, it does not actually clear it immediately.
You can either call the RemoveAll() or Clear() methods for instant deletion of the objects, or issue a Response.Redirect call to the page itself and re-test for the existence of the data.

Categories