首页 新闻 会员 周边 捐助

ASP.NET单点登陆

0
悬赏园豆:40 [已解决问题] 解决于 2011-12-10 16:44

我做好了一个单点登陆,但是发现如果用户不点击退出按钮而是直接关闭浏览器那登陆过的用户就不能再登陆系统,下面这是我单点登陆所用的代码

Session["sKey"] = txtUserName.Text;
                                string sUser = Convert.ToString(Cache[Session["sKey"].ToString()]);
                if (sUser == null || sUser == String.Empty)
                {
                    TimeSpan SessTimeOut = new TimeSpan(0, 0, System.Web.HttpContext.Current.Session.Timeout, 0, 0);
                    HttpContext.Current.Cache.Insert(Session["sKey"].ToString(), Session["sKey"].ToString(), null, DateTime.MaxValue, SessTimeOut,
                    System.Web.Caching.CacheItemPriority.NotRemovable, null);
                    Response.Redirect("Default.aspx");
                }
                else
                {
                    ScriptManager.RegisterStartupScript(this, this.GetType(), "js1", "alert('该帐号已经登陆了该系统,不能重新登陆!');", true);
                    return;
                }

劳烦各位大虾,请问当用户登陆之后关闭浏览器怎么释放掉Cache呢

①尘不染的主页 ①尘不染 | 初学一级 | 园豆:11
提问于:2011-03-10 16:55
< >
分享
最佳答案
0

关闭浏览器的时候怎么才能让他执行退出里的事件,将用户直接从集合中删除呢,这个时候我们就要想到全局应用程序Global.asax的Session_End事件中处理。意思就是说我们可以设置session的过期事件,然后再过期后在session_End事件中处理这些事件,部门代码如下:

 void Session_End(object sender, EventArgs e)
    {
        //在会话结束时运行的代码。
        // 注意: 只有在 Web.config 文件中的 sessionstate 模式设置为
        // InProc 时,才会引发 Session_End 事件。如果会话模式
        //设置为 StateServer 或 SQLServer,则不会引发该事件。
        string strUserId = Session["user"] as string;
        ArrayList list = Application.Get("user_list") as ArrayList;
        if (strUserId != null && list != null)
        {
            list.Remove(strUserId);
            Application.Add("user_list", list);
        }
    }

web.config中

<sessionState mode="InProc" timeout="1"></sessionState> 

但是,如果session的过期时间这么少,那么相应的用户就要不停的操作,否则就会过期,所以我们要相应的做一下处理,让session在半小时内不过期,始终保持有效,半小时后在不操作就会过期,当然,如果用户直接关闭浏览器,那么一分钟后Session也会过期。这样就可以满足要求了

在每个页面中加入如下的javascript(这些javascript也可以写在共通里,每个页面引入就可以了)

以下是引用片段:
  var x=0;
  function myRefresh()
  {
  var httpRequest = new ActiveXObject("microsoft.xmlhttp");
  httpRequest.open("GET", "test.aspx", false);
  httpRequest.send(null);
  x++;
  if(x<60) //60次,也就是Session真正的过期时间是30分钟
  {
  setTimeout("myRefresh()",30*1000); //30秒
  }
  }
  myRefresh();


  在web.config中设置

以下是引用片段:
<sessionState mode="InProc" timeout="1"></sessionState> 


  test.aspx页面就是一个空页面,只不过需要在Page_Load中加入:

以下是引用片段:
  Response.Expires = -1;

原理就是:设置Session的过期时间是一分钟,然后在每个页面上定时每30秒连接一次测试页面,保持Session有效,总共连60次,也就是30分钟。如果30分钟后用户还没有操作,Session就会过期。当然,如果用户直接关闭浏览器,那么一分钟后Session也会过期。这样就可以满足要求了

所以这两种情况一结合,我们就可以直接都在Global.asax的Session_End事件中处理就可以了,在退出的事件中,我们直接将session会话取消就可以了

Session.Abandon();

这样就会执行Session_End事件了!

收获园豆:40
奋斗张 | 小虾三级 |园豆:514 | 2011-03-11 08:24
能不能给个具体点的实例给我啊 我用了你那个没有用啊 我调试的时候也进不去Session_End事件里面啊,我的Session_End事件里面是这样写的:
System.Web.Caching.Cache cache = new Cache(); ;
cache.Remove(Session["sKey"].ToString());
Session.Clear();
在这个事件里面还能获取到Session的值吗
你Q是多少啊 我们在Q上说或者会更直观点
①尘不染 | 园豆:11 (初学一级) | 2011-03-11 12:14
Session.Abandon();

后台代码执行这句看是否执行Session_End事件。
奋斗张 | 园豆:514 (小虾三级) | 2011-03-11 14:49
其他回答(1)
0

在global.asax里面的session_end事件里清楚掉相应的cache就行了!

哲 思 | 园豆:280 (菜鸟二级) | 2011-03-14 12:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册