I would like to display number logged-In users count in my page. I implemented this using Application Variable, but the problem is its not decreasing the count when user close the browser.
First i opened the web application using IE the count became 1, then i opened the app using firefox the count became 2. When i close any one of the browser the count not getting decrease.
void Application_Start(object sender, EventArgs e)
{
Application["UsersCount"] = 0;
}
void Application_End(object sender, EventArgs e)
{
}
void Session_Start(object sender, EventArgs e)
{
if (Application["UsersCount"] != null)
{
Application.Lock();
Application["UsersCount"] = ((int)Application["UsersCount"]) + 1;
Application.UnLock();
}
}
void Session_End(object sender, EventArgs e)
{
Application.Lock();
Application["UsersCount"] = ((int)Application["UsersCount"]) - 1;
Application.UnLock();
}
Any other way to achieve this?
Thank you.!
This is not so simple to implement. To be logged in doesn`t actually necessary mean that user doing something. You should set some timeout (probably the same as auth cookie life-time) and check the last activity mark of each user. Special DB table is good for that, but if you want quick and dirty solution:
You can keep IDictionary<Guid, DateTime> which you will update on each request. Guid is for UserID, DateTime for the last activity. On each request (probably somewhere in MasterPage code behind) you update this dictionary with current DateTime. Then you can check count of IDs with DateTime less than timeout.
IDictionary<Guid, DateTime> userActivityLog = Application["UserActivityLog"] as IDictionary<Guid, DateTime>;
DateTime timeout = DateTime.Now.AddHours(-1); // one hour timeout
int loggedCount = userActivityLog.Count(x => x.Value > timeout);
Related
I use the following code to count the number of currently open sessions in my ASP.NET (2.0/3.5) application (ASMX web service, legacy code), but if it runs long enough the count stops matching the built in performance counters (my count is higher, Session_End seems to not be invoked sometimes). The sessions are InProc. What might I be missing?
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Application["OpenSessionCount"] = 0;
}
protected void Session_Start(Object sender, EventArgs e)
{
Application.Lock();
Application["OpenSessionCount"] = (int)Application["OpenSessionCount"] + 1;
Application.UnLock();
/* Set other Session["foo"] = bar data */
}
protected void Session_End(Object sender, EventArgs e)
{
Application.Lock();
Application["OpenSessionCount"] = (int)Application["OpenSessionCount"] - 1;
Application.UnLock();
}
}
"Just use performance counters!"
Yes, I'm just asking because I'm curious where I went wrong.
The Session_End is invoked in two situations:
When Session.Abandon() is called
Immediately after the Session expires
If you close the browser, the Seesion_End event fire when Session Expires.
See MSDN lib
Sessions do not actually begin unless you store something in the Session dictionary. So, you won't get a Session_End event for any that don't actually have a session object allocated.
From MSDN:
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.
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
Application["OpenSessionCount"] = 0;
}
protected void Session_Start(Object sender, EventArgs e)
{
Application.Lock();
// Store something every time to ensure the Session object is allocated.
HttpContext.Current.Session["dummy"] = "Foo";
Application["OpenSessionCount"] = (int)Application["OpenSessionCount"] + 1;
Application.UnLock();
/* Set other Session["foo"] = bar data */
}
protected void Session_End(Object sender, EventArgs e)
{
Application.Lock();
Application["OpenSessionCount"] = (int)Application["OpenSessionCount"] - 1;
Application.UnLock();
}
}
Reference: ASP.NET: Session.SessionID changes between requests
I've just started learning ASP.NET and I'm facing a problem with getting textbox values. I want to do a simple calculator with only 4 basic operations but what happens is that after I click the + sign and click Go, I see that I didn't store the first number at all. Second number is fine though. Here is a sample of my code.
public partial class deafult : System.Web.UI.Page
{
public TextBox output = new TextBox();
public double temp,tempAdd, calc;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnAdd_Click(object sender, EventArgs e)
{
tempAdd = Convert.ToDouble(output.Text);
output.Text = String.Empty;
}
//User enters another number after clicking Add button then clicks Proc
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
}
I debugged and tempAdd is always 0 but I get the number in temp. temp variables and calc is defined public.
You essentially have the problem with all of your variables being re-initialized on load of the page. Unlike winforms, web is stateless.
There are ways of persisting state between refreshes, however. The most obvious choice for your application would be to only go to the server once with the both values and what you want to do with them. ie One button click.
However, for personal edification, it may be worth looking up ViewState. This allows you to store values in an array of sorts and retrieve them even after a refresh.
There are also Session and Application level arrays in ASP.NET that work in similar ways.
Every time you call the page (by events) all your properties is initialized.
Try to do all your logic in one event or store your properties in manager / service / db.
In web (Asp.Net) on every postback properties will get cleared, try to use ViewState or Session variables to hold these values. Refer Asp.Net State Management concepts from MS.
Hope this may help you.
Web controls are State less so you should user session sate to hold the first value then do your stuff...
Ex:-
protected void btnAdd_Click(object sender, EventArgs e)
{
Session["tempAdd"] = output.Text;
output.Text = String.Empty;
}
protected void proc_Click(object sender, EventArgs e)
{
temp = Convert.ToDouble(output.Text);
string oldval=Session["tempAdd"] != null ?Session["tempAdd"].ToString() :"";
if(oldval!="")
tempadd=Convert.ToDouble(oldval);
calc = tempAdd + temp;
output.Text = calc.ToString();
}
I want to program an app with C# and Awesomium for remembering that a user is logged into the site. For this I use the following code:
private void button1_Click(object sender, EventArgs e)
{
Uri link = new Uri("http://www.mywebsite.com");
webControl1.Source = link;
string Values="";
WebSession session = WebCore.CreateWebSession("d:\\temp", WebPreferences.Default);
session.SetCookie(link, Values, true, true);
}
But when I close and run the app again, I must log in again.
How can I do this?
Looks like you're setting the last parameter to true in your call to the SetCookie function - This means you're setting a session cookie not a persistent cookie that will be saved to disk
private void button1_Click(object sender, EventArgs e)
{
Uri link = new Uri("http://www.mywebsite.com");
webControl1.Source = link;
string Values="";
WebSession session = WebCore.CreateWebSession("d:\\temp", WebPreferences.Default);
session.SetCookie(link, Values, true, **false**);
}
Reference: See here
So, as part of an assignment I am trying to roughly calculate the time taken for a transaction to be reviewed and completed in an ASP.NET Web Forms project using CSharp.
In my ASPX page, I am showing the details of the objects in the cart.
And there is a button which confirms the checkout and completes it.
What I need to calculate is the time since the page loaded, till the checkout was confirmed.
Here there are two events: page_load and checkoutbutton_click
So in the code behind file I am
public partial class CheckoutReview : System.Web.UI.Page
{
public Stopwatch sw = new Stopwatch();
protected void Page_Load(object sender, EventArgs e)
{
sw.Start();
//... code
}
protected void checkoutbutton_click(object sender, EventArgs e)
{
//...code
sw.Stop();
// in the database i am then storing the elapsedMilliSeconds of the stopwatch
}
The problem however is that with this code the elapsed time is remained 0 all the time.
If I put the same stopwatch however in the checkoutbutton_click() the stopwatch works fine.
Can someone kindly explain what I am doing wrong here?
Each time the page is posted back to the server, a new instance of the class CheckoutReview is being created... so what you're seeing is the time between the creation of the class on the post-back and the event handler.
You have to remember that each request to the server (whether it's the original page request, or a post-back) is an individual call to the server. Things like Session and ViewState exist to allow you use data between those requests.
I would recommend you store the current time in the ViewState of the page on the initial load, and then check the TimeSpan difference in the event handler...
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// Only store on first visit to the page
ViewState["pageLoadTime"] = DateTime.Now;
}
}
protected void checkoutbutton_click(object sender, EventArgs e)
{
TimeSpan diff = DateTime.Now - (DateTime)ViewState["pageLoadTime"];
}
So i have the code..
int var1 = 0;
protected void cmdvar1_Click(object sender, EventArgs e)
{
var1= var1+ 10;
lblvar1.Text = var1.ToString();
}
And when clicking this, its great.. it takes the int, adds 10 to it, then displays it.. however it won't display any more than 10, did some playing around and came to the conclusion, that its not because the label isnt updating, it just simply isnt adding 10 to the previous 10 on the variable. What am i doing wrong? What am I mising? Do i need to store the variable info in a cookie or something?
This is due to the lifecycle of ASP.NET. Storing private fields behind the web page isn't the same as how it works with WinForms. If you want to persist information across post backs you need to store it in some persistent storage i.e. Session/ViewState/Database etc.
private int var1 = 0;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
// load var1 from cache
Int32.TryParse((Session["var1"] ?? 0).ToString(), out var1);
}
}
protected void cmdvar1_Click(object sender, EventArgs e)
{
var1 += 10;
Session["var1"] = var1; // cache var1
lblvar1.Text = var1.ToString();
}
So I would strongly suggest looking into a different platform. Perhaps ASP.NET MVC... However you can use something like the following to get arround your problem.
private int MyNum
{
get{ return (int)ViewState["MyNum"] ?? 0; }
set { ViewState["MyNum"] = value; }
}
Then just use MyNum as your integer your incrementing.
Assuming that lblvar1 is a Label control then you can do the following. The reason this will work is because .NET automatically take care of the state of UIControl
protected void cmdvar1_Click(object sender, EventArgs e)
{
var var1 = Convert.ToInt32(lblvar1.Text);
var1= var1+ 10;
lblvar1.Text = var1.ToString();
}
As suggested in the comments, you have to wrap your universe around statelessness before you will get to producing meaningful web applications.
The ASP.NET equivalent to accomplish state-like behavior is to use the Session collection which is available to every web page.
protected void cmdvar1_Click(object sender, EventArgs e)
{
int var1 = (int)Session["yourInteger"];
var1 += 10;
Session["yourInteger"] = var1;
lblvar1.Text = var1.ToString();
}
You are obviously setting an initial value for Session["yourInteger"] somewhere else, just one time.
The problem with Session is that it makes your application potentially buggy and somewhat unscalable. The more you use it, the worse on both accounts.
Use Session body, HTTP is a stateless Protocol, once you postback you loose the current variable value,
Solution:
int var1=0;
protected void cmdvar1_Click(object sender, EventArgs e)
{
if(Session["var1"]!=null)
var1=int.Parse(Session["var1"].ToString());
else
var1=0;
var1= var1+ 10;
lblvar1.Text = var1.ToString();
Session["var1"]=var1;
}