Detect Session Timeouts / Distinguish Between First Visit & Session Timeout - c#

When a user goes to the sign in page, I want to detect if their session timed out and was redirected to this page, so a friendly message could be displayed.
I set isTimeout = true when the session is a new session and when the cookie["ASP.NET_SessionId"] is not null. But isTimeout was set to true when if it was a first visit too. How do I distinguish the first visits from timeouts?
Thanks in advance!

In your Global.asax there is a method called Session_End to handle just this.
You can use this to add whatever functionality you need. Such as setting TempData["IsTimeout"] to true (if you are using ASP.NET MVC). This will then persist past the redirect and is accessible on your log in view. It will then be destroyed.
E.g. In your Global.asax.cs
protected void Session_End(Object sender, EventArgs e)
{
TempData["IsTimeout"] = true;
}
In your log in view:
<%: ((bool)(TempData["IsTimeout"] ?? false)) ? "For security reasons you were timed out, please log in again" : "" %>

Related

MVC 4 Lose Session Because Redirects From www.website.com to website.com

I just realize that session is lost when redirecting from www.website.com to website.com without www.
However I am quite lucky that I can set up the server so all redirection is start with www. In the future I do not want my application to be server dependent, I want to make it code dependent.
For example:
#Html.Hidden("PageManagerUrl", Url.Action("PageManager","Admin"))
produces /Admin/PageManager/, and I use location.href = url (when url is /Admin/PageManager/.
It is not 100% sure that I will lose my session at the first time of redirection, but when I tested it but redirecting back and forward, about the 3rd or 4th time, the session will be lost. After I set up the server setting to:
Preferred domain * www.website.com
Select the URL (either with or without the www. prefix) to which site visitors will be redirected via a SEO-safe HTTP 301 redirect.`
The session is never lost again. So I wonder, how to do the best redirection without losing my session? Please give me example how to do it from controllers and javascript / views.
Do you have any global.asax file ?
If yes, then please check whether it contains these two methods signature.
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}

Redirect from Global.asax

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

Redirecting to another page on Session_end event

I would like to auto-redirect to login page when session time outs.
In web.config file, i have the following code
<configuration>
<system.web>
<sessionState mode="InProc" timeout="1"/>
</system.web>
</configuration>
In Global.asax file-
protected void Session_End(object sender, EventArgs e)
{
Response.Redirect("LoginPage.aspx");
}
But after time-out, i am receiving the following error:
HttpException was unhandled by user code.
Response is not available in this context.
Any clue to solve this issue?
Session_End is called when the session ends - normally 20 minutes after the last request (for example if browser is inactive or closed).
Since there is no request there is also no response.
I would recommend to do redirection in Application_AcquireRequestState if there is no active session. Remember to avoid loops by checking current url.
Edit: I'm no fan of .Nets built in authentication, Example goes in Global.asax:
protected void Application_AcquireRequestState(object sender, EventArgs e)
{
try
{
string lcReqPath = Request.Path.ToLower();
// Session is not stable in AcquireRequestState - Use Current.Session instead.
System.Web.SessionState.HttpSessionState curSession = HttpContext.Current.Session;
// If we do not have a OK Logon (remember Session["LogonOK"] = null; on logout, and set to true on logon.)
// and we are not already on loginpage, redirect.
// note: on missing pages curSession is null, Test this without 'curSession == null || ' and catch exception.
if (lcReqPath != "/loginpage.aspx" &&
(curSession == null || curSession["LogonOK"] == null))
{
// Redirect nicely
Context.Server.ClearError();
Context.Response.AddHeader("Location", "/LoginPage.aspx");
Context.Response.TrySkipIisCustomErrors = true;
Context.Response.StatusCode = (int) System.Net.HttpStatusCode.Redirect;
// End now end the current request so we dont leak.
Context.Response.Output.Close();
Context.Response.End();
return;
}
}
catch (Exception)
{
// todo: handle exceptions nicely!
}
}
If you are using something like FormsAuthentication for maintaining the security of your application, then this part (that part that you are trying to do) will be done for you. If FormsAuthentication discovers that a user's session has expired it will redirect him or her back to you login page.
Second, don't rely too much on Session_End because it will never trigger if you change session provider from InProc to SQLServer or other out of process provider.
You can use session property IsNewSession to detect whether it is session timeout or not.
The ASP.NET HttpSessionState class has IsNewSession() method that returns true if a new session was created for this request. The key to detecting a session timeout is to also look for the ASP.NET_SessionId cookie in the request.
Definitely I too agree that we should put the below code in some so called a custom BasePage, which is used by all pages, to implement this effectively.
override protected void OnInit(EventArgs e)
{
base.OnInit(e);
if (Context.Session != null)
{
if (Session.IsNewSession)
{
string CookieHeader = Request.Headers["Cookie"];
if((CookieHeader!=null) && (CookieHeader.IndexOf("ASP.NET_SessionId") >= 0))
{
// redirect to any page you need to
Response.Redirect("sessionTimeout.aspx");
}
}
}
}
check this link for more explanations if you want to put the above code in a base page class .
You should use Application_AcquireRequestState
You'll find that Application_AuthenticateRequest no longer has a session context (or never had one).
In my research into this I cam across this post which solved it for me.
Thanks go to Waqas Raja.
asp.net: where to put code to redirect users without a session to the homepage?
I think you are getting "Response is not available in this context" because the user is not making a request to the server, and therefor you cannot provide it with a response. Try Server.Transfer instead.
The easiest way what I feel is to use Meta information and get the trick working. Consider we have a page WebPage.aspx add the below code in the the WebPage.aspx.cs file.
private void Page_Load(object sender, System.EventArgs e){
Response.AddHeader("Refresh",Convert.ToString((Session.Timeout * 60) + 5));
if(Session[“IsUserValid”].ToString()==””)
Server.Transfer(“Relogin.aspx”);
}
In the above code, The WebPage.aspx is refreshed after 5 seconds once the Session is expired. And in the page load the session is validated, as the session is no more valid. The page is redirected to the Re-Login page. Every post-back to the server will refresh the session and the same will be updated in the Meta information of the WebPage.aspx.
you can simply do the following in web.config
<configuration>
<system.web>
<sessionState mode="InProc" timeout="1" loginurl="destinationurl"/>
</system.web>
</configuration>
Since, we can't redirect from Session_End as no response/redirect is present there.By using this you will be redirected to destinationurl when session will timeout.Hope this helps.

Is this possible to clear the session whenever browser closed in asp.net?

In my asp.net application, i want to clear the session whenever my browser closed or my tab (if my browser containing multiple tabs)closed.
Please guide me to get out of this issue...
Short version, No.
There's no solid way of a server detecting if the client has closed their browser. It's just the nature of web development's asynchronous pattern.
Long version, if it's really, really important to you;
Put a bit of javascript in the page that sends a regular post to your website in the background and set up a serverside agent or service that disposes of the sessions if it doesnt receive these regular "heartbeat" signals.
You can put a javascript postback onto the page's unload() event but dont rely on it, it doesnt always fire.
This happens by default whenever you close your browser, and that's not just for ASP.NET. It's for most server-side programming languages that have a session state. Basically, any cookie that is added that doesn't specify an expiration date, will be deleted when the browser is closed.
Where this doesn't apply, is when you close a tab, which is something you will not have any control over because the tab close event will not get sent back to the Web server.
You can try to do that with javascript. Check it at:
http://www.codeproject.com/Tips/154801/How-to-end-user-session-when-browser-closed
Alternatively you can check you previous session state on every new browser opening and can Session.clear() or Session.abandon() the previous session.
this will make sure that every time you start application you will get new session.
use BasePage in your .net application.
Check the session.sessionid on basepage load.
More Inforamtion how to detect new session in basepage. BasePage.Session.Link
Hope this helps
regards
Shaz
public class BasePage : Page
{
protected string mySessionId;
private CurrentUser _currentUser;
public CurrentUser _CurrentUser
{
get { return ((CurrentUser)HttpContext.Current.Session["myCurrentUser"]); }
set { _currentUser = value; }
}
protected override void OnLoad(EventArgs e)
{
if (Session["myCurrentUser"] != null)
{
if (_CurrentUser.ProUser)
{
mySessionId = Session.SessionID; // it means New Session
}
if (!mySessionId.IsNullOrDefault() && mySessionId != Session.SessionID)
{
Session.Abandon(); //Abandon current session and start new one
}
}
}
}
I think cookies can better meet your requirement here for session management.
it means that session data should not be stored on the server and
should be with your call, so that you don't have to worry about
clearing the data on server.
Yes.First of all Browser automatically clear session when browser is closed. you can try to capture browser close or tab close event in browser using javascript function like on before unload and on unload. Mostly onbefore unload event captures browser close event in chrome, Firefox, IE 11.
You can use Session_End event of Global.aspx
//For Specific Session
Session.Remove("SessionName");
//All the Session
Session.Abandon();

Cache page but count hits

I have an aspx page which counts every visit and creates a cookie. But if I use OutputCache page counts only the first visitor who requested the page. How can I prevent this bug?
Page directive:
<%# OutputCache Duration="1200" VaryByParam="mode;page;sid;tid" %>
Codebehind:
protected void Page_Load(object sender, EventArgs e)
{
//Load single post data
#region Hit Counter
//hit counter lasts during session
if (Session["LastHit" + postId] == null)
{
cmmnd.CommandText = "UPDATE Posts SET Hits=Hits+1 WHERE PostID=#PostID;";
cmmnd.ExecuteNonQuery();
Session["LastHit" + postId] = 1;
}
#endregion
}
This isn't a bug, but by design. The page is not re-processed if it is in the cache and "the cached output is still valid". You can run code during this validation phase and this could help you perform the task of counting the visits and adding it to a cookie. The following might be of help:
Caching ASP.NET Pages
How to: Check the Validity of a Cached Page
What is the point of this count? Marketting information? Use a lightweight analytics counter from script or an image in the page, not mixed in with generating the page itself. The bug is that you're adding extra work to the busier requests, instead of giving the extra work its own request.

Categories