Session gets lost on navigation to a new page on asp.net - c#

On authentication, the email of the user is retrieved and stored as session data like below
protected void Page_Load(object sender, EventArgs e)
{
string email = Request.Form["email"];
HttpContext.Current.Session["email"] = email;
Server.Transfer("Home.aspx");
}
The email is successfully stored but when I navigate to a new page and try to retrieve the session value like below. I see the session has been lost
var email = (string)Session["email"] ?? "";
I already enabled session state in web.config
<pages enableSessionState="true">
<sessionState timeout="20" mode="InProc">

Setting rquireSSL to false in web.config fixed the issue.
<httpCookies requireSSL="false" />

In asp.net application when use server.transfer its not work,because instead of use server.transfer use Response.Redirect("Home.aspx")
That's why causing issue not getting session value in home page.
Also check this link hope will usefull for this
Server.Transfer causing Session exception

Related

Session Start Global.asax C# ASP.NET

I have the following code:
protected void Session_Start(object sender, EventArgs e)
{
WindowsPrincipal p = Thread.CurrentPrincipal as WindowsPrincipal;
string sUserAccount = HttpContext.Current.User.Identity.Name.ToString();
HttpContext.Current.Session["WinAccount"] = sUserAccount;
}
The code is to get the windows user name. From the session_start, I want to create a session which called WinAccount. But, when I tried to call the session from one of my page (default.aspx) which is has master page on it.
Let say, on page_load:
string sWinAccount = Session["WinAccount"].ToString();
Label1.Text = sWinAccount.ToString();
The web.config looks like:
<authentication mode="Windows"/>
<identity impersonate="false"/>
<authorization>
<deny users="?"/>
</authorization>
Also, the properties of the project has been enabling the windows authentication mode.
When I run, it blanks.
Please advise.
Thank you.
Verify if the application is using Windows Authentication (check web.config). If you are providing custom or forms authentication, you will need to set user details on success handler, not the session start; and use CustomPrincipal rather than WindowsPrincipal .
If windows authentication is enabled, the user credential will be available on the very first request (session start) and can be retrieved are you mentioned in your code. Place a debugger in session start and verify if you are retrieving it properly or not.
try
string sUserAccount =System.Security.Principal.WindowsIdentity.GetCurrent().Name.Tostring();
Session_Start event fired when a new client start their very first request to the app, not when the user is logged in. So in your case, the HttpContext.Current.User.Identity.Name is empty at the time Session_Start is called. It worked as expected.

asp.net c# - setting session then redirecting users via global.asax

hello I'm trying so hard for this, I cant understand most question since this is my first time developing in ASP.NET here is my problem.
Im declaring session variable when the user click the submit in the login page then redirecting them to somepage.aspx
if (dt.Rows.Count > 0)
{
Session["usersId"] = usersId;
Session["usersLevel"] = usersLevel;
Session["usersRegion"] = usersRegion;
Session["notification"] = "";
Response.Redirect("pages/Dashboard.aspx");
}
So after that that I put something in my Web.config
<system.web>
<compilation debug="true" targetFramework="4.0"/>
<sessionState timeout = "1" mode = "InProc" />
</system.web>
So ofcourse the session will expire?/timeout? then in my Global.asax I put this
void Session_End(object sender, EventArgs e)
{
Response.Redirect("Login.aspx");
}
However an HttpExeception rises, that says
Response is not available in this context.
Why did the response is not available? when it said that the sessionstate mode must be set to InProc? I just want the user to be redirected in that page when the session expires/timeout(I dont know their difference but looks same to me)
thank you
You may consider to do the redirect in AuthenticateRequest event. Only inProc sessionstate provider supports session end event and it may happen any time(even after the relevant request is responsed, that's why you saw that exception).

HttpCookie vs Response.Cookie

Hello fellow developers,
I'm a little new to working with cookies in ASP.NET and I apologize if this is a basic question. So I have the following code in my web.config that I was kind of playing around with to get an understanding of cookies.
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
Now here is my question. I created a cookie in two ways (which I needed to secure).
One way I secured it was with this code-
protected void btnSubmit_Click(object sender, EventArgs e)
{
HttpCookie cookie = new HttpCookie("UserInfo");
cookie.Secure = true; // secure the cookie
cookie["username"] = txtEmail.Text;
if (txtEmail.Text != "")
{
Response.Cookies.Add(cookie);
}
Response.Redirect("WebForm2.aspx");
}
Now when I used this code to create it, I got the UserInfo cookie to be secured in this way was well.
protected void btnSubmit_Click(object sender, EventArgs e)
{
Response.Cookies["UserInfo"]["userName"] = txtEmail.Text;
}
Now here is my question. Why does using "Response.Cookies" default to using the settings in the web.config? How come when I create a cookie using HttpCookie I have to secure it by setting it to true in the CS code? My best guess was that since I'm creating an instance of HttpCookie, that is why but I wanted further direction on this.
Many Thanks!
Why does using "Response.Cookies" default to using the settings in the
web.config?
The simple/direct answer is this is by design.
Assuming the cookie doesn't existing when you call
Response.Cookies["UserInfo"]["userName"] = txtEmail.Text;
The cookie is created for you and assigned the value but is given the defaults that you specified in:
<httpCookies httpOnlyCookies="true" requireSSL="true"/>
However, if you were to instantiated as you already pointed out and add it to the collection, it will use those manually set values, which in the case of a new HttpCookie, the Secure property default value is false;
As specified in the Cookies Collection docs
You can get up close and personal with the code for HttpCookieCollection as well to see more of the "why".

Session time out very short in hosting environment? Test for the loss of sessions?

My sessions timeouts are very short on my hosting environment, some times even 2 seconds and they timeout.
The sessions are reset if the user continues to use the website, unless the session = null and the count is 0.
The sessions should time out after 20min and then redirect the user to the log in page
The code for this is below:
protected override void OnInit(EventArgs e)
{
if (this.Session != null && this.Session.Count > 0)
{
string email = (string)this.Session["Email"];
int practiceId = (int)this.Session["PracticeId"];
int practitionerId = (int)this.Session["PractitionerId"];
this.ClientScript.RegisterHiddenField("loggedInUserName", email);
this.ClientScript.RegisterHiddenField("practiceId", practiceId.ToString());
this.ClientScript.RegisterHiddenField("practitionerId", practitionerId.ToString());
}
else
{
this.Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));
Response.Redirect("~/Default.aspx");
}
base.OnInit(e);
}
Does anyone know why my session timeout could be so short?
When using my site sometime i can move around for 2-5 minutes with no timeout and other time 10s in i get a time out. What could cause session being lost, are they any ways to avoid or test for the loss of sessions?
Thanks in advance.
I assume you are overriding the init function for the page, but potentially abandoning the session on every page load could cause more issues than it solves. I would check for the existence of the session inside the master page:
protected void Page_Init(object sender, EventArgs e)
{
if (!HttpContext.Current.User.Identity.IsAuthenticated)
{
// user is not logged in
string ReturnUrl = HttpContext.Current.Request.Url.PathAndQuery;
string RedirectUrl = "/Login.aspx";
if (!String.IsNullOrEmpty(ReturnUrl))
{
RedirectUrl += "?ReturnUrl=" + Server.UrlEncode(ReturnUrl);
}
Response.Redirect(RedirectUrl);
}
}
If this is in the master page it will check on each request (made to an aspx page that inherits from the master) that will redirect the user to the login page.
If your app is sharing an application pool, you might be sharing the cookie id with another application:
<authentication mode="Forms">
<forms loginUrl="~/Login.aspx" timeout="60" name="MY_COOOKIE_NAME" slidingExpiration="true" />
</authentication>
<sessionState timeout="60" />
The MY COOKIE NAME will identify the cookies your app uses, other apps might have the default cookie name, so your sessions although apparently authenticated don't belongto the app as they are getting overwritten by a different app. The sliding expiration means that your session time will be extended everytime you visit a page.
Also, check that the machineKey config element is present, this made my sessions more stable:
<machineKey
validationKey="random_validation_key"
decryptionKey="random_decryption_key"
validation="SHA1" decryption="AES" />

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.

Categories