根据具体项目要求,我采用了SQLServer会话状态模式;
WebConfig配置文件中Session配置如下:
    
<!--配置SESSION开始-->
    <sessionState
   mode="SQLServer"
   cookieless="false"
   sqlConnectionString=" Integrated Security=SSPI;data source=192.168.9.243\SQLEXPRESS"
   sqlCommandTimeout="20" />
    <!--配置SESSION结束-->
针对SQLServer会话状态模式这种方式,我有几点疑问,请大家解惑
1、我把cookieless="false"设置成了FALSE,那浏览器是怎么在一个会话中维持同一个Sessionid的?
我用firebug查看过,第一次请求页面的时候,响应头信息里没有set-Cookie的信息,但是请求头信息里已经有了Cookie的信息,他们之间的第一次交互式怎么样?
以后的每一次都是只有请求信息里有Cookie信息,以后的每一次交互中,这些请求头的Cookie信息是保存在浏览器当中?2、我这里采用的事SQLServer会话状态模式,MSDN和网上的帖子的解释是这种模式是将Session保存到数据库当中。
我查看了ASPState数据库内的ASPStateTempSessions,其中有SessionId的选项,严格来说是Sessionid和applicationid的组合。我的疑问是,如果我在程序当中执行如下语句
Session["userName"] = "admin";
那么这个键值对是保存在数据库中?我如何能查看到?
3、关于Session作为权限判断的使用方法,大家都是怎么来使用?
直接在登陆的时候写入一个Session键值对,然后在其他页面读取,如要为空则认为没登陆或者Session超时?其实这个Session值应该对应一个Sessionid才对是不是?
还是用的其他方法对Session进行使用?这些是我的疑问,或者大家觉得权限方面还有比Session更好的都可以提供给我。谢谢先。

解决方案 »

  1.   

    这个跟Request对象Session有何区别
      

  2.   

    Session["userName"] = "admin"; 
    其中userName就是id
      

  3.   

    Session["userName"] = "admin"; 
    那么这个键值对是保存在数据库中?这个不清楚,没用过这种模式
      

  4.   

    session记录用户角色,通过角色,模块,用户等实现权限控制Session服务器配置指南与使用经验 
      

  5.   

    1. 第一次请求时就有cookie很正常,因为浏览器会提交信息,例如在所访问网站下注册的保存在磁盘的cookie的信息。asp.net网站的SessionID在cookie中是 ASP.NET_SessionId,你只需要观察这个东西的生命就可以了,其它的cookie无关。实际上,由于它是cookie中的,所以Session集合中所有数据丢失时,SessionID也不会丢失。2. 既然你已经说出了键值对,其实你自己就回答了。我没有跟踪过SQL Server状态服务方式,不过我想如果我来设计,那么一个Session值肯定是这样的联合主键:“应用程序进程ID+SessionID+key”,而其值我可能会保存为两个字段:“实例化类型、xml序列化值”。实际上,根据这个结构自己写一个Session持久化程序或许也很简单(或许不超过50条语句),并且在global.asax中在请求的开始和结束运行或许比使用后台数据库更快很多倍。在每一个请求结束时,将Session数据保存到服务器app_data目录下一个xml文件中(文件名可以用SessionID来生成),在每一个请求开始时首先判断是否某个Session集合中的元素丢失了,如果丢失了就从xml文件中恢复所有的值装入Session集合。只要考虑到并行写文件时容错问题,以及定期清理多余文件。3. asp.net保证只为你的程序装入当前线程的SessionID所对应的那些Session元素,或者明白点说,它其实也是在每一个请求开始时动态地产生一个Session对象然后给你逐一装入Session集合中的元素的。
      

  6.   

    说实在地,写了这个东西,我觉得自己写一个Session持久化服务要比使用微软提供的两种方式都简单,而且比使用SQL Server要快捷得多。为什么不自己写呢?我以前都是建议别人不使用Session集合,自己来实现数据持久化。
      

  7.   

    “应用程序进程ID”改为应用程序进程位置(path)似乎更好。如果使用进程ID反而让进程重启时把对象丢失了。或者取消这个也可以,只要asp.net确实能保证SessionID相当随机(实际上也确实是)。
      

  8.   

    关于对Session的理解,请楼主看这篇文章:http://www.cnblogs.com/Rayinuk/archive/2005/01/31/99670.html
    对于你说的Session做权限的问题,我们现在也用到了,我是这样做的判断用户登录超时,
    if (HttpContext.Current.Session["LoginUserID"] == null)
                    {
                        //用户超时加这个
                        string _headInfo = HttpContext.Current.Request.Headers.Get("X-Requested-With");
                        if (_headInfo != null && _headInfo.ToLower().Equals("xmlhttprequest"))
                        {
                            HttpContext.Current.Response.AddHeader("sessionstatus", "timeout");
                        }
                        return false;
                    }
    希望对你有用!
      

  9.   

    你可以把他单独写作一个类或者方法,哪里用就哪里调用!最好加上Try Catch监控一下!
      

  10.   

    这个userName应该是Session集合的索引key吧。
    SessionId是用来标记唯一的会话或者Session集合的吧。
      

  11.   


    嗯。谢谢sp1234的用心解答和建议。
    1、一开始载入第一个aspx页面之后在请求头信息里就已经有了ASP.NET_SessionId,这个应该是握手之后服务前端生成的Sessionid写入客户端的Cookie,用来标记此次会话。“实际上,由于它是cookie中的,所以Session集合中所有数据丢失时,SessionID也不会丢失。”这句我很认同,我这么做的主要目的就是为了持久化Session集合,为了防止Session丢失;
    2、刚才又重新查看了下ASPState数据库内的ASPStateTempSessions,原来SessionItemShort这个字段里存储的就是具体的Session集合的值,以二进制格式进行的存储。我想我们在程序内部使用Session集合来存储变量的的时候还是对键值对之间赋值和取出即可,具体的数据库到内存内的Session集合(哈希表)的映射应该是交给asp.net底层机制来实现的吧。另外sp1234 给出的自定义持久化的建议非常值得参考,好像asp.net 会话模式就是支持自定义模式。
      

  12.   


    1. 在第一个Http请求的header里面当然是没有任何Cookie的,除非你自己实现一个浏览器。而当服务器处理完这个请求并发回Reponse的时候,会包含"Set-Cookie"的值在header里面,也就是说服务器会把sessionId返回给客户端。之后客户端用同一个sessionId来访问后续的页面,就可以保证session不丢失。所以写入sessionId这个动作并不是发生在所谓的“握手”之后。
    2. 保存在数据库端的Session的内容都是序列化之后的,所以你看到的是二进制,并没有使用多么高深的算法。你要自己实现一种session存储模式,当然是可行的,但是请切记:不要真的以为自己被微软高明多少。