【问题标题】:Can Session Timeout and FormAuthentication Timeout make this effect,how will i change it?Session Timeout 和 FormsAuthentication Timeout 可以产生这种效果,我将如何改变它?
【发布时间】:2014-12-09 19:04:05
【问题描述】:

我有 Asp.net 网站项目。我正在使用 Global.asax 文件查找活动用户号(活动会话);

void Application_Start(object sender, EventArgs e) 
{
    // Code that runs on application startup
    Application["UsersOnline"] = 0;
}
void Session_Start(object sender, EventArgs e) 
{
}
void Session_End(object sender, EventArgs e) 
{
    Application.Lock();
    Application["UsersOnline"] = (int)Application["UsersOnline"] -1 ;
    Application.UnLock();
}

这是登录页面,我在用户登录时增加应用程序状态;

protected void Login1_Authenticate(object sender, AuthenticateEventArgs e)
        {
            string connectionstring = WebConfigurationManager.ConnectionStrings["LocalSqlServerTracking"].ConnectionString;
            string sqlstring;
            sqlstring = "Select Name,Password,ID,SessionStateID from Employee where Name=@UserName and Password=@Password";

            SqlConnection con = new SqlConnection(connectionstring);
            SqlCommand command = new SqlCommand(sqlstring, con);

            command.Parameters.Add(new SqlParameter("@UserName", Login1.UserName));
            command.Parameters.Add(new SqlParameter("@Password", Login1.Password));
            System.Data.SqlClient.SqlDataReader reader;

            // open a connection with sqldatabase
            try
            {
                using (con)
                {
                    con.Open();

                    reader = command.ExecuteReader();

                   Boolean read= reader.Read();
                   online = Convert.ToInt32(reader["SessionStateID"]);
                    if (read)
                    {
                       Session["Name"] = Login1.UserName;
                        Session["Password"] = Login1.Password;
                        Session["ID"] = reader["ID"].ToString();
                        int ID = Convert.ToInt32(Session["ID"]);
                        var matches = from p in entities.Employees
                                      where p.ID ==ID
                                      select p;
                        // Execute the query and return the entity object.
                       Employee emp = matches.Single();
                        // Change the entity object.
                        emp.SessionStateID = 0;
                        // Commit the changes back to the database.
                        entities.SaveChanges();
                         Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;
                        e.Authenticated = true;

                    }

                    else {

                            Label1.Text = "User not exist";
                            e.Authenticated = false;
                }

现在如果我登录 Applications State 增加到 1,注销并登录后仍然为 1,如果使用新标签 以相同用户登录另一个用户应用程序状态增加到2。效果很好。但是经过一段时间后,我登录并看到负值,例如 -7 。我唯一能想到的是会话超时。如果我使用 Session.Abandon() 一段时间后会话超时仍然有效吗?我将如何防止它,不应该是这样,或者如果有什么我看不到它会是什么?

   <forms loginUrl="login.aspx" defaultUrl="userHome.aspx" timeout="60" />
  <sessionState cookieless="true" cookieName="ASP.NET_SessionId" regenerateExpiredSessionId="false" timeout="5" mode="InProc"></sessionState>

【问题讨论】:

  • 您是否在您的网站中使用了最喜欢的图标?是 MS MVC 吗?我在论坛上发现了一些用户抱怨 Session_Start 被调用两次的帖子。有人说这是因为他们使用了favicon.ico(很奇怪)。无论如何,您仍然应该尝试映射 looged 用户以检查是否有效。
  • 没有常规的 Asp 网站项目。

标签: c# asp.net session global-asax


【解决方案1】:

您应该有两个不同的应用程序变量并相应增加:

Application["UsersOnline"]
Application["LoggedUsers"]

只要您已登录的用户退出并且您的会话被放弃,您就会将该用户重定向到您网站中的另一个页面,对吗?如果是这样,ASP.NET 可能会为同一用户创建另一个会话并增加Application["UsersOnline"]

您只会在 20 分钟(或其他配置的值)内看到过期会话、不再提出请求的人、帖子的减少。

如果您想跟踪Application["LoggedUsers"],请确保在用户登录时增加此数字并在注销时减少。此外,请确保在Session_End 上发现会话是否为已登录用户。如果是这样,则减少Application["LoggedUsers"]

编辑

完整的解决方案是这样的。

  1. 保持登录事件不变。

  2. 我不知道你是怎么做到的,但你的注销应该是这样的:

     public BtnLogout_Click(object sender, EventArgs e)
     {
         Session.Abandon();
     }
    
  3. 将您的 Session_End 更改为:

     void Session_End(object sender, EventArgs e) 
     {
        if(!String.IsNullOrEmpty((string)Session["Name"]))
        {
            Application.Lock();
            Application["UsersOnline"] = (int)Application["UsersOnline"] -1 ;
            Application.UnLock();
        }
     }
    

当您调用Session.Abandon() 时,会话被标记为删除,但不会立即删除。这意味着您可以在Session_End 上执行一些清理工作。这正是我们正在做的事情。

我们希望确保我们只为登录的用户减少 Application["UsersOnline"],而不是那些有会话的用户(实际上是每个调用该网站的人,这取决于您构建页面的方式)。这保证了我们只会减少之前增加变量的用户。

【讨论】:

  • @YourSolutionPartner 不,LoggedUsers 仅在用户登录时增加。您在注销时减少它,但在会话到期时也会减少它(不是每个人都会按注销,只需关闭浏览器......所以你会等到会话结束......所以这意味着在 Session_End 上减少 ALSO)。
  • @YourSolutionPartner 太棒了!我要求创建这两个变量,以便您可以看到差异。不要忘记也减少Session_End!我很高兴能帮上忙! :)
  • 请使用新代码更新您的问题,以便我们为您提供帮助
  • @YourSolutionPartner 好的,这应该给你方法。
猜你喜欢
  • 2019-04-10
  • 2011-05-02
  • 1970-01-01
  • 2019-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-11
  • 2020-07-12
相关资源
最近更新 更多