Losing session data in ASP.NET - c#

I moved an ASP.NET site running on a server with .NET 1.1 to another server running with .NET 2.0.
In one of the pages I have the following code to detect an expired session:
protected void Page_Init(object sender, System.EventArgs e) {
if ( Session["XBCPEmail"] == null ) {
Response.Redirect("signin.aspx?expired=yes");
return;
}
}
(Session["XBCPEmail"] == null) is resolving as true (as if the session had expired) in one unexpected case, after clicking one of the buttons of the page. It happens with only one of the buttons. Just like other buttons in the same page, the button event handler ends with this code redirecting to the same page:
Response.Redirect("cpanel.aspx");
I checked and at the time of Response.Redirect("cpanel.aspx"); the value of (string)Session["XBCPEmail"] is a valid string, so I'm not sure what can happen between the Response.Redirect and the Page_Init that could be making the Session["XBCPEmail"] become null.
Which could make a Session variable in .NET 2.0 become null? This code does not have that issue in 1.1 and, even in 2.0, it only affects one button on the page.
UPDATE: The issue only occurs if the button event handler calls an external .exe program, with the code below. If this code is commented out, the Session variable is not null. How can the creation of an external process to run a command line program have any impact on if a Session variable is null or not?
private string CallBridge3(string task, string arg1, string arg2, string arg3) {
Process process = new Process();
process.StartInfo.FileName = MapPath("bridgefcp.exe");
process.StartInfo.Arguments = "-" + task + " \"" + arg1 + "\" \"" + arg2 + "\" \"" + arg3 + "\"";
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
string output = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return output;
}
UPDATE 2: The problem has vanished after installing .NET 4.5 on the Windows 2008 R2 with IIS 7.5 machine, instead of using the one that came by default, which was .NET 2.0.

By default Response.Redirect terminates thread execution and there might be a race conditions in setting session variables. It is described in article Don't redirect after setting a Session variable (or do it right), so try to use another, less violent version:
Response.Redirect("cpanel.aspx", false);

Check your web.config, maybe you have this tag
<httpCookies requireSSL="true" />
If it so, remove it.

You need to update web.config as mention below :
<httpCookies requireSSL="false" />

I was facing the same issue and tried every option mentioned in the above answers.
Finally found that the issue was that we had marked session cookie as secure in our project but were running it with http
If the server has not been setup for SSL and you try to mark the cookie secure, a new session will be generated for each request.
So finally enabling back https fixed it for me.

I believe your session in the web.config is being reset (getting a new SessionID for each postback)
You could try to debug this by putting the SessionID somewhere on the page (for testing) with
HttpContext.Current.Session.SessionID
This did happen on one of my websites and all i had to do was go into IIS and resave the SessionState Panel

Just go to your web.config file and edit your sessionstate tag. Set requiressl to false from true.

I encountered this problem when setting the Session variable before a redirect. I had enableSessionState="ReadOnly" in Web.config. It happens because the session does not exists and the redirect happens before the client can set the session cookie.
My solution was to set a dummy Session variable in the previous page load (login page in my case).
protected void Page_Load(object sender, EventArgs e)
{
// Put this in master page or login page
Session["createSession"] = true; /* ensure there's a cookie for session */
}

<httpCookies requireSSL="false" />
Removing this from the local web.config worked for me. The issue was only happening when running the app locally.
Removed the setting from web.config
Added it to the web.staging.config and web.production.config

For MVC, make sure the web.config has below configuration.
<httpCookies httpOnlyCookies="true" requireSSL="false" />
in <system.web> section

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).

Postback Fails On Default Document

So I've created a Web Application (not Web Site) with ASP.NET (C#) and it compiles just fine in the VS13 environment. But when I publish it on IIS, the Postback on the Default Document fails. The Default Document is called LoginPage.aspx. As soon as I click the <asp:Button> to run my code behind, all it does is refresh the page. This project has been published on my local 127.0.0.1 IP address for the time being.
I know this has been a documented issue, but I've tried many solutions and have not come across a resolution. Some solutions I have attempted:
Creating a brand new Web App with minimal code to attempt accessing any Postback with no success.
I tried the first solution presented here with no success: https://stackoverflow.com/a/7367076/4204026
I also tried URL mappings:
<urlMappings>
<add url="~/login" mappedUrl="~/Views/LoginPage.aspx" />
<add url="~/login/" mappedUrl="~/Views/LoginPage.aspx" />
</urlMappings>
I'm honestly at a loss as to what's happening here. One thing I did notice is when the application is being run through Visual Studio, the <form> tag on the LoginPage.aspx appears in Chrome as:
<form method="post" action="LoginPage" id="ct101" class=".myForm">
Through IIS:
<form method="post" action="./" id="ct101" class=".myForm">
Not sure if that's a problem either. I tried hard-coding the action to login to see what would happen and it does redirect to the correct page, but as suspected no Postback was fired - My Session variable returned null and no query string was used.
Here's the related LoginPage.aspx front-end code (trimmed out a bunch of unrelated HTML):
<%# Page Title="DREW KENNEDY | WELCOME" Language="C#" MasterPageFile="Site.Master" AutoEventWireup="true" CodeBehind="LoginPage.aspx.cs" Inherits="MyMedia.Views.LoginPage" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<!-- form is located on Site.Master -->
<asp:Button OnClick="LoginBtn_Click" CssClass="login" runat="server" name="submit" Text="Sign In" />
</asp:Content>
And the LoginBtn_Click method in LoginPage.aspx.cs:
protected void LoginBtn_Click(object sender, EventArgs e) {
//Tried the following line while commenting out everything else to make sure Postback is being ignored
//Response.Write("<script>alert('Test');</script>");
try {
AbstractPersistenceDecorator decorator = new PersistenceDecorator();
string uname = username.Text.Trim();//username is a TextBox Control
string pass = password.Text.Trim();//password is a TextBox control
bool isCookieRequested = CheckBox.Checked;
if (decorator.authenticate(uname, pass)) {//calling SQL Server for authentication
User AuthenticatedUser = (User)Session["User"] ?? decorator.getUserInfo(uname);
if (Session["User"] == null) Session["User"] = AuthenticatedUser;
if (isCookieRequested) {
HttpCookie cookie = new HttpCookie("username", AuthenticatedUser.Username);
cookie.Expires.AddDays(7);
Response.Cookies.Add(cookie);
} else {
Session.Timeout = 15;
}
Thread.Sleep(1600);
//string redirect = string.Format("dashboard?username={0}", AuthenticatedUser.Username);
Response.Redirect("dashboard?username=" + AuthenticatedUser.Username);
}
} catch (Exception ex) {
//who cares?
}
}
Final pieces of info:
Running IIS 8.0
Application created with 4.5 Framework, Application Pool is also 4.5 Framework
I have ensured that ASP.NET is installed on IIS
I do have URL ReWriting in the global.asax file, though I'm not sure if that is related in any way (I don't see how).
I have no Default.aspx page
EDIT:
Just tested the project through 127.0.0.1 on IE11 and FF with the same result.
EDIT #2:
Additional things I have tried with no success:
I tried removing my URL Rewriting
I tried adding an empty URL Rewrite rule, i.e. ("Empty URL", "", "~/Views/LoginPage.aspx")
Additional notes:
I do not use Telerik
I do not use ISAPI
The project in Visual Studio was set to debug and not release
I apologize for not giving enough information in the OP as I have found the answer. It turns out it had nothing to do with ASP.NET, but rather SQL Server. I stripped the code bare and after adding back one piece of code at a time and stripping away all exception handling, I found through IIS that IIS APPPOOL\.NET vX.X did not have permissions to access the database.
What I had to do is:
In MSQLSM, add a new Login for IIS APPPOOL\.NET v4.5
Further on, I found out that it needed the correct permissions to perform certain commands after receiving the following exception:
The SELECT permission was denied on the object 'X', database 'X', schema 'dbo'
This Was Solved Here
Give that new Login the proper access. Login Properties > User Mapping > checking db_datareader and public.
The code behind now executes. It still leaves the question why it was prohibiting any Postbacks, even if I removed any SQL Connectivity in the code behind. Very strange.
Anyway, thanks to those who helped.
I suggest that you redirect from the default page to the Expected page then this should work. Iis default page handling is done through isapi to handle static content so the post data may not survive

My Session variable is always null

I'm creating a movie ticket reservation project. I want to get username from page1 and display it on page2 (using session variable)
Page1:
string uname = TextBox1.Text;
Session["UName"] = uname;
Session.Timeout = 30;
Page2:
if ((string)Session["UName"] != null)
{
string user = (string)Session["UName"];
}
and I placed a sign out button in page2 to remove session variable value. But the session variable is always null.
I've already used cookies in the page1 and will this be a cause? or what else? Please Help. Thanks in advance.
This usually occurs when doing a Response.Redirect after setting the session variable. You can work around this issue by calling the overload instead:
Response.Redirect("...", false); // false = don't stop execution
//causes ASP.NET to bypass all events and filtering in the HTTP pipeline
//chain of execution and directly execute the EndRequest event
HttpContext.Current.ApplicationInstance.CompleteRequest();
The underlying issue is a ThreadAbortException which is often ignored because it doesn't break the application. This is a known issue, and you can learn more about it here: http://support.microsoft.com/kb/312629.
Side Note
On a side note, you shouldn't be resetting your Session.Timeout value in the code like that. I can't be sure, but that may also have an adverse affect on your logic. Instead, you should specify the session timeout in the web.config under the system.web section:
<sessionState timeout="60" />
See this answer on when the Session can be null:
What should I do if the current ASP.NET session is null?
I personally often ran into this issue when I was using async requests with completion callback. In these callbacks I wanted to set something in the session and it was null.
I also had same problem,
I was toggling between debugging two different sites on localhost and there were two cookies for the session ID.
I deleted the cookies via Chrome's developer tools [Press F12 in Browser]->Application->Storage->Cookies

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