ASP. NET Session variable expires much faster - asp.net

I set a session variable at login:
HttpContext.Current.Session["user_key"] = res; //being some string eg: "asd"
HttpContext.Current.Session.Timeout = 60;
Just in case i also have
<system.web>
<sessionState timeout="60"></sessionState>
Then i need to check for the user and get some date for their ID on pretty much every page and on every Page_load:
if(HttpContext.Current.Session["user_key"]!= null)
{
sesvar = (string)(context.Session["user_key"]);
}
else
{
HttpContext.Current.Response.Redirect("/login/");
}
This works for the most part. But it is definitely not 60mins. I'd get "kicked" (redirected to login) every now and then and can't figure out why.
Also the project is worked on and maintained trough Dreamweaver. Being a WebSite it is not compiled in any way and is live on IIS Server.

It turned out to be a function in our Database ruining every hour which "cleaned" the login table, where it shouldn't have.

Related

Understanding the JIT; slow website

First off, this question has been covered a few times (I've done my research), and, for example, on the right side of the SO webpage is a list of related items... I have been through them all (or as many as I could find).
When I publish my pre-compiled .NET web application, it is very slow to load the first time.
I've read up on this, it's the JIT which I understand (sort of).
The problem is, after the home page loads (up to 20 seconds), many other pages load very fast.
However, it would appear that the only reason they load is because the resources have been loaded (or that they share the same compiled dlls). However, some pages still take a long time.
This indicates that maybe the JIT needs to compile different pages in different ways? If so, and using a contact form as an example (where the Thank You page needs to be compiled by the JIT and first time is slow), the user may hit the send button multiple times whilst waiting for the page to be shown.
After I load all these pages which use different models or different shared HTML content, the site loads quickly as expected. I assume this issue is a common problem?
Please note, I'm using .NET 4.0 but, there is no database, XML files etc. The only IO is if an email doesn't send and it writes the error to a log.
So, assuming my understanding is correct, what is the approach to not have to manually go through the website and load every page?
If the above is a little too broad, then can this be resolved in the settings/configuration in Visual Studio (2012) or the web.config file (excluding adding compilation debug=false)?
In this case, there are 2 problems
As per rene's comments, review this http://msdn.microsoft.com/en-us/library/ms972959.aspx... The helpful part was to add the following code to the global.asax file
const string sourceName = ".NET Runtime";
const string serverName = ".";
const string logName = "Application";
const string uriFormat = "\r\n\r\nURI: {0}\r\n\r\n";
const string exceptionFormat = "{0}: \"{1}\"\r\n{2}\r\n\r\n";
void Application_Error(Object sender, EventArgs ea) {
StringBuilder message = new StringBuilder();
if (Request != null) {
message.AppendFormat(uriFormat, Request.Path);
}
if (Server != null) {
Exception e;
for (e = Server.GetLastError(); e != null; e = e.InnerException) {
message.AppendFormat(exceptionFormat,
e.GetType().Name,
e.Message,
e.StackTrace);
}
}
if (!EventLog.SourceExists(sourceName)) {
EventLog.CreateEventSource(sourceName, logName);
}
EventLog Log = new EventLog(logName, serverName, sourceName);
Log.WriteEntry(message.ToString(), EventLogEntryType.Error);
//Server.ClearError(); // uncomment this to cancel the error
}
The server was maxing out during sending of the email! My code was fine, but, viewing Task Scheduler showed it was hitting 100% memory...
The solution was to monitor the errors shown by point 1 and fix it. Then, find out why the server was being throttled when sending an email!

I can't get my account to authorise itself using linqtotwitter

I know this has been asked many times before, but I have used info from the linqtotwitter docs and examples along with other posts on here to get this far. I can get my new app to send a tweet, but only by letting it take me to twitters authorise page and me having to click the authorise button to continue.
The app itself is authorised fine, so I don't need my password each time, it's just the use of the app that it wants permission for.
I know the reason for this is because nowhere in my code is there my access token or access token secret. I have added them in but every time I get a 401 unauthorised (invalid or expired token).
My code is as follows, perhaps you can see where I'm going wrong?
private IOAuthCredentials credentials = new SessionStateCredentials();
private MvcAuthorizer auth;
private TwitterContext twitterCtx;
public ActionResult Index()
{
credentials.ConsumerKey = ConfigurationManager.AppSettings["twitterConsumerKey"];
credentials.ConsumerSecret = ConfigurationManager.AppSettings["twitterConsumerSecret"];
credentials.AccessToken = "MYaccessTOKENhere"; // Remove this line and line below and all works fine with manual authorisation every time its called //
credentials.OAuthToken = "MYaccessTOKENsecretHERE";
auth = new MvcAuthorizer
{
Credentials = credentials
};
auth.CompleteAuthorization(Request.Url);
if (!auth.IsAuthorized)
{
Uri specialUri = new Uri(Request.Url.ToString());
return auth.BeginAuthorization(specialUri);
}
twitterCtx = new TwitterContext(auth);
twitterCtx.UpdateStatus("Test Tweet Here"); // This is the line it fails on //
return View();
}
Here's the FAQ that has help on resolving 401 errors: http://linqtotwitter.codeplex.com/wikipage?title=LINQ%20to%20Twitter%20FAQ&referringTitle=Documentation
A couple items that might be helpful too:
You can't tweet the same text twice - so either delete the previous tweet with the same text or change the text. All my test append DateTime.Now.ToString() to avoid this error.
The SessionStateCredentials holds credentials in SessionState. The persistence mode default for Session state is InProc, meaning that your session variables will be null if the process recycles, which will happen unpredictably. You might want to make sure that you are using either StateServer or SQL Server modes.

Best way to persist data locally for a user on a webpage?

I have a search box on the page (webservice-fed results) and I'd like to save the search TERMS for the user in a UL\LI list on the page. So the next time they come back to the page, the results are still there....but if they clear their cache then it gets reset.
What's the best way to go about that?...I can persist between postbacks easily, but this is a new one for me.
Thanks,
Steve
Probably use a cookie, but remember you're limited to 4kb of data.
Otherwise, store the session in a database. Then save that records ID to a cookie. That way you can load the data from the database based on the ID in the cookie. Then just flush any entries in DB older than say, 30 days or something.
Due to lack of sleep, I have given you an answer in PHP. Sorry about that, I'll leave it because the information is still correct, just the syntax will be slightly different in asp.net
You have two options for data-persistence in php; cookies and sessions.
Sessions are server-side, and last as long as the browser window stays open.
Cookies are client-side, and last until the user clears their cache.
So it sounds like you want a cookie option. So in your search query processor, add the line
setcookie('search_' . time(), $_POST['search_query'], (time() + 10368000));
This will create a cookie on the client machine, with the name search_xxxx where xxxx is a timestamp (each cookie has to have a unique name otherwise they will overwrite eachother).
The weird looking calculation at the end is an expire time, which is set to 120 days in the future.
Then in your php document that displays your search page, you need to spit out all these cookie values.
foreach($_COOKIES as $k => $v) {
if(substr($k, 0, 7) == 'search_') echo($v . '<br />');
}
This will spit out each of the search terms found on the clients machine. The if statement is to make sure it only displays search term cookies, and no others.
Use a cookie. Assuming you start with a List<string> of search terms called terms, do:
var sb = new StringBuilder();
foreach (var t in terms) sb.Append(t).Append(";")
var c = new HttpCookie("terms");
c.Value = sb.ToString().TrimEnd(';');
c.Expires = DateTime.Now.AddDays(30);
Response.Cookies.Add(aCookie);
Then when you need to access those terms again (to databind to a Repeater, or process in some other way for display on your page):
if (Request.Cookies["terms"] != null) {
var terms = new List<string>();
foreach (var t in Request.Cookies["terms"].Value.Split(';')) list.Add(t);
}
A Cookie is probably your solution for today, but HTML5 localStorage will eventually be the best bet. Only supported by modern browser versions right now, depends on your users.

Session is timing out on the drop down selected index change

Session is timing out on the drop down selected index change
20 minutes ago | LINK
Hello Everyone,
I am facing a weird problem here. I have a report page on which i am using a drop down list which has different years. When user select the year=2009, i am displaying report for 2009 data. The code is given below. The website is live on our web server now. The page access havy data, so sometime it takes one minute or more to load the report for selected year and when that is the case my session expires and user is getting redirected to the default page. But the same thing works fine in the solution in my machine and in one of our local server. It is just not working on our live server. Please help me by posting the solutions if you know any.
I have also placed this line in my web.config but it is not helping:
Code:
protected void ddlYear_SelectedIndexChanged(object sender, EventArgs e)
{
if (Session["UserId"] != null)
{
Session["IsDetailedReportLoaded"] = false;
Session["IsScoreCardLoaded"] = false;
Session["IsChartLoaded"] = false;
Session["IsReportLoaded"] = false;
string strYear = ddlYear.SelectedValue;
LoadReport(Convert.ToInt16(strYear));
lblYear.Text = strYear;
lblAsOf.Text = strYear;
lblYear.Text = ddlYear.SelectedValue.ToString();
lblAsOf.Text = ddlYear.SelectedValue.ToString();
ddlYearDetail.SelectedValue = ddlYear.SelectedValue;
ddlYearScorecard.SelectedValue = ddlYear.SelectedValue;
ddlYearGraph.SelectedValue = ddlYear.SelectedValue;
mpeLoading.Hide();
}
else
Response.Redirect("Default.aspx");
}
Thanks,
Satish k.
One possible problem could be that the web server is running out of memory and forcing the app pool to recycle. This would flush the InProc Session memory. You could try using Sql Session State instead and see if that resolves the problem. Try monitoring the web server processes and see if they're recycling quickly.
You can place a
if(Session.IsNew)
check in your code and redirect/stop code execution appropriately.
I would check the Performance tab in IIS to see whether a bandwidth threshold is set.
Right click on website in IIS
Performance tab
Check "Bandwidth throttling" limit
If a treshold is set you might be hitting the maximum bandwidth (KB per second) limit. Either disable bandwidth throttling, or increase the limit.

Get ASP.NET Session Last Access Time (or Time-to-Timeout)

I'm trying to determine how much time is left in a given ASP.NET session until it times out.
If there is no readily available time-to-timeout value, I could also calculate it from its last access time (but I didn't find this either). Any idea how to do this?
If you are at the server, processing the request, then the timeout has just been reset so the full 20 minutes (or whatever you configured) remain.
If you want a client-side warning, you will need to create some javascript code that will fire about 20 minutes from "now". See the setTimeout method.
I have used that to display a warning, 15 minutes after the page was requested. It pops up an alert like "your session will expire on {HH:mm}, please save your work". The exact time was used instead of "in 5 minutes" as you never know when the user will see that message (did he return to his computer 10 minutes after the alert fired?).
For multi-page solution one could save last request time in cookie, and javascript could consider this last access time for handling warning message or login out action.
I have just implemented a solution like the one asked about here and it seems to work. I have an MVC application and have this code in my _Layout.chtml page but it could work in an asp.net app by placing it in the master page I would think. I am using local session storage via the amplify.js plugin. I use local session storage because as Mr Grieves says there could be a situation where a user is accessing the application in a way that does not cause a page refresh or redirect but still resets the session timeout on the server.
$(document).ready(function () {
var sessionTimeout = '#(Session.Timeout)'; //from server at startup
amplify.store.sessionStorage("sessionTimeout", sessionTimeout);
amplify.store.sessionStorage("timeLeft", sessionTimeout);
setInterval(checkSession, 60000); // run checkSession this every 1 minute
function checkSession() {
var timeLeft = amplify.store.sessionStorage("timeLeft");
timeLeft--; // decrement by 1 minute
amplify.store.sessionStorage("timeLeft", timeLeft);
if (timeLeft <= 10) {
alert("You have " + timeLeft + " minutes before session timeout. ");
}
}
});
Then in a page where users never cause a page refresh but still hit the server thereby causing a reset of their session I put this on a button click event:
$('#MyButton').click(function (e) {
//Some Code that causes session reset but not page refresh here
amplify.store.sessionStorage("sessionTimeout", 60); //default session timeout
amplify.store.sessionStorage("timeLeft", 60);
});
Using local session storage allows my _Layout.chtml code to see that the session has been reset here even though a page never got refreshed or redirected.
You can get the timeout in minutes from:
Session.Timeout
Isn't this enough to provide the information, as the timeout is reset every request? Don't know how you want to display this without doing a request?
Anyhow, best way is on every request setting some Session variable with the last access time. That should provide the info on remote.

Resources