I have a site with multiple pages, not necessarily heirarchical. I want to query the user's identity (using AD...) whenever the user first enters the site, and create session state variables for the convenience of other pages as needed. A user could possibly enter the site without going through the default.aspx page, so I thought I'd put the code in the Master Page's code-behind.
On the assumption this is a good idea, versus some sort of static class that maintains this information, I started setting it up, but found the Master Page code-behind doesn't always seem to get fired when I enter the site. Is this a debugging phenomenon, or am I right, and the Master Page is the wrong place to put this code...?
I would recommend using the Global.asax class. You'll need to add it to your web app if it's not already there. Once you have it, you can then use the various events (session start and end, app start and end and error) to implement business logic particular to what you need exactly.
I tend to monkey around with the logged in user in the Application_PreRequestHandlerExecute event of the global.asax. This will allow you to look at the User Principle (eg - User.Identity.Name) to see who is logged in (or if they're not logged in) and do what you need to (such as set Session information for the user, etc.).
Here's a tidbit of code I've got on one .NET web app that uses the Global.asax for storing user data in the Session.
protected void Application_PreRequestHandlerExecute(Object sender, EventArgs e) {
if (Context.Handler is IRequiresSessionState || Context.Handler is IReadOnlySessionState) {
SetUserItem();
}
}
private void SetUserItem() {
if (Session["UserItem"] == null)
Server.Execute("~/SetSessionUserObj.aspx", true);
}
... and then the SetSessionUserObj.aspx.cs
protected void Page_Load(object sender, EventArgs e) {
string ID = User.Identity.Name;
MyUser myUser = new MyUser();
UserItem userItem = myUser.GetUserItemByID(ID);
if (userItem != null) {
Session["UserItem"] = userItem;
}
}
This is just one manner that you can go about accessing a user's identity in the global.asax. You don't necessarily have to go about doing a Server.Execute to set user data (I just did it for other reasons that fall outside the scope of this question).
Good luck.
Related
Saw so many articles and links related to the same concept.
Counting online users using asp.net
Is there any ASP.NET application to monitor online user and page view log report?
Mine is little different. My application is MVC4 and using SimpleMembershipProvider. I am not sure why GetNumberOfUsersOnline is not working.
https://msdn.microsoft.com/en-us/library/system.web.security.membership.getnumberofusersonline(v=vs.110).aspx
Any Ideas ? How to do this in a easy and efficient way. I am just using this in only one place in my website.
I found this online it it looks like it will work for you. Just add this code to your Global.asax.cs file:
protected void Application_Start(Object sender, EventArgs e)
{
Application.Lock();
Application["UserCount"] = 0;
}
protected void Session_Start(Object sender, EventArgs e)
{
Application.Lock();
Application["UserCount"] = (int)Application["UserCount"] + 1;
Application.UnLock();
}
protected void Session_End(Object sender, EventArgs e)
{
Application.Lock();
Application["UserCount"] = (int)Application["UserCount"] - 1;
Application.UnLock();
}
Then when you need to access the user count you can use:
var count = (int)Application["UserCount"];
You can use signalR to track connected users. Using this you can get count online efficiently & Real Time and also track connected users information. You can put condition to track logged in users also. So, Go with latest technology. You can implement with existing MVC application.
You can refer this official tutorial for the same.
http://www.asp.net/signalr
Another nice solution that is pleasantly orthogonal to your code is Google Analytics. http://www.google.com/analytics/ Using GA, you can see a real-time display of active users on your website. It also helps that you have a history over time and can see peaks and valleys of user activity.
From Microsoft documentation:
GetNumberOfUsersOnline returns the number of users for the current ApplicationName where the last-activity date is greater than the current time less the UserIsOnlineTimeWindow. The last-activity date/time stamp is updated to the current date and time when user credentials are validated by way of the ValidateUser or UpdateUser method or when a call to a GetUser overload that takes no parameters or one that uses the userIsOnline parameter to specify that the date/time stamp should be updated.
You can see that GetNumberOfUsersOnline depends on multiple parameters and isn't efective.
As a workaround I suggest that you could nherits SqlMembershipProvider and override the GetNumberOfUsersOnline(), so you cam implement your logic here.
public class MyMembershipProvider : SqlMembershipProvider
{
public override bool ValidateUser(string username, string password)
{
if (base.ValidateUser(username, password))
{
// successfully logged in. add logic to increment online user count.
return true;
}
return false;
}
public override int GetNumberOfUsersOnline()
{
// add logic to get online user count and return it.
}
}
Just decrement online user count logic in user log out
If you want track visitors and pages visited, here some idea:
track with httpmodule
Visitor Real-time Session
You may try to read the performance counters listed here :
Current Anonymous Users is the number of anonymous IIS users
Current Non-Anonymous Users is the number of authorized IIS users
Let's say that in an ASP.NET .aspx page I have the Page Load method and another method for a button click event.
In the Page Load method I'm checking if the user is logged in by checking the Session. Whether he is or not, I'm storing the result in a Global Variable.
Boolean isGuest = false;
protected void Page_Load(object sender, EventArgs e) {
if(Session["id"]==null)
isGuest = true;
else
isGuest = false;
}
Let's say 20 minutes have passed, and I don't know if the Session has terminated or not, and then I click a Button, the event goes like this:
protected void Button_Click(object sender, EventArgs e) {
if(isGuest==false)
//do something
else
// do another thing
}
My Question is : When I'm clicking the button, does ASP.NET go through the Page_Load method again (check isGuest again) or it simply executes what's inside the Button_Click method, means, it uses a Boolean isGuest that could be false, but in reality the session is terminated, means it should be true.
Page_Load is triggered always before the control events.
Have a look: ASP.NET Page Life Cycle Overview
Side-note: If you want to do things only on the first load and not on every postback you have to check the IsPostBack property.
You can:
Define your own class with the UserID, and other profile properties;
Add that class to session in the global.asax session started event Session["NameReferingToYourClass"] = new YourClass();
Set a member variable to your session object early in the page life cycle mYourClass = Session["NameReferingToYourClass"] casted if you need to;
Then you can make any changes to your class anywhere in the code your member variable is available;
Save back your class with all the changes into session on the Page.Unload(..){ Session["NameReferingToYourClass"] = mYourClass.
This way you are using your class properties in your code, including UserId, pretty much like a windows application, there will be no mentioning of session anywhere else in your code.
i am developing a web application in which students give their exams. Here is requirement to show which students are logged in in admin and faculty panel. First i have update a column in database named flag which turns to 1 on logged in time and on logged out turns to 0. But when browser forcefully closed it can not be updated. for this, i have used java script method, which fires whenever we navigate to another page and shows the student logged out.
Is there any solution for the same.
There is no easy way to update your user's status as soon as he closed the browser without logging out. You could use the Session_End event in Global.asax, but that will be triggered when the session expires (usually 20 minutes).
Also, in Session_End you have no information about the authenticated user, only the session id.
If you are using ASP.NET Membership to authenticate your users, there is a method that does what you need
Membership.GetNumberOfUsersOnline()
Add this code on your Global.asax Page
public void Session_Start(object sender, EventArgs e)
{
// Fires when the session is started
Application["UserCount"] = Convert.ToInt32(Application["UserCount"].ToString()) + 1;
}
public void Session_End(object sender, EventArgs e)
{
// Fires when the session ends
Application["UserCount"] = Convert.ToInt32(Application["UserCount"].ToString()) - 1;
}
Add this code on your Master Page
private void Page_Load(System.Object sender, System.EventArgs e)
{
//Put user code to initialize the page here
this.lblUserCount.Text = "Users online " + Application["UserCount"].ToString();
}
Or
If you use the built-in ASP.NET membership provider, then there's the ever-so-handy Membership.GetNumberOfUsersOnline() method.
Im fairly new to asp.net and am having a hard time finding information about this topic.
I am building a website which will allow users to upload videos. If the videos, for example, are inappropriate or off topic, I can suspend their account so the next time they sign in, they will be redirected to a "Your account has been suspended" page. What I'm trying to figure out is whats the best way to handle the following situation: I suspend a user's account AFTER they have just signed in. So they have already passed validation during the sign in process. I basically would like the user to be redirected to that "Your account has been suspended" page after the next action they perform. Besides checking the database on every postback (which seems a bit inefficient), what would be the best way to handle this?
Please let me know if you need more information or a better example.
Thank you any help
Here is my approach. Create a new BasePage and inherit your aspx pages from this class instead of System.Web.UI.Page.
public class BasePage : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
if (!IsPostBack)
{
// I assume you already get the user's profile
if (User.IsSuspended)
Response.Redirect("/SuspendedPage.aspx");
base.OnInit(e);
}
}
}
Updated:
There are a lot of ways to store a value through out the application life cycle. Here is one of them.
// Global.asax.cs
void Application_AuthenticateRequest(object sender, EventArgs e)
{
if (HttpContext.Current.User != null &&
HttpContext.Current.User.Identity.IsAuthenticated)
{
HttpContext.Current.Items["User"] =
GetUserByUsername(HttpContext.Current.User.Identity.Name);
}
}
In one of the ASP.NET MVC apps we would like to logoff the user automatically if he closes the browser tab in which the app is opened.
We are using the following code when he authenticates.
FormsAuthentication.SetAuthCookie(userName, false)
As of now, if we closes the browser window and relaunch it, users are asked to authenticate again. But we want to ask users to authenticate again if they close the tab and try to access any of the website urls.
We decided to use cookie less authentication so that the authentication token is part of the url. When the tab is closed and they open the website again, they will be asked to authenticate again :)
I have not tried this myself, but I think the following approach should work:
On the client side, you can use the OnUnload event of your document to launch a javascript function that would call your server-side signout method via ajax.
On the server side, you should have the action method call FormsAuthentication.SignOut() and Session.Abandon();
A browser clears all Session scoped objects only when it is completely closed, and not when an individual tab is closed.
One way could be to use a very low Session timeout and have a server-side script poll every few seconds to hit an object on the page. This will extend Session time again. So if a tab is closed, the script can't find the object thereby allowing the Session to timeout. One problem here is if your app is on a pretty high load, your app could DoS itself!
Actually there is no way we can LogOff the user when the user closes the browser tab. The only way for this is to check if the the user is authenticated when we call the LogOn method in the Controller.
This code is an example of how I do it in ASP.Net MVC 3.
public ActionResult LogOn()
{
if (Request.IsAuthenticated)
{
FormsAuthentication.SignOut();
return RedirectToAction("Index","ProductManager");
}
return View();
}
You can simply use session variables to automatically log off anybody trying to return to the secured destination page. Create a single session variable (integer or boolean) and in the onclick event of your login button reset it to a known state after acknowledging that the user has a valid credential then set or increment that session variable in the page_load event of the page your trying to secure. Test these values and signout the user if he is trying to return to the page or do nothing if otherwise. The code may look similar to this.
protected void btnLogin_Click(object sender, EventArgs e)
{
if (IsAuthenticated == true)
Session["IsUserLoggedIn"] = (int)0;
}
protected void Page_Load(object sender, EventArgs e)
{
if (HttpContext.Current.User.Identity.IsAuthenticated == true)
{
if (Session["IsUserLoggedIn"] != null)
{
int IsUserLoggedIn = (int)Session["IsUserLoggedIn"];
if (IsUserLoggedIn <= 0)
{
Session["IsUserLoggedIn"] = (int)IsUserLoggedIn + 1;
}
else
{
Session["IsUserLoggedIn"] = (int)0;
FormsAuthentication.SignOut();
FormsAuthentication.RedirectToLoginPage();
}
}
}
else { Session["IsUserLoggedIn"] = (int)0; }
}