很多开发人员喜欢在ASP.NET程序中使用Session,用它来记录当前登录用户的一些信息。但是在SharePoint 2010系统中,默认是禁用Session功能的。如果在一个应用程序中使用了Session,你很可能会发现代码会抛出一个“引用的对象没有实例化”异常。如果通过Visual Studio调试一下代码,就能发现HttpContext.Session属性返回的是null。
要在一个SharePoint 2010程序中使用Session,开发人员会面临一些潜在的问题。SharePoint 2010系统很可能被部署为一个服务器场的模式,它可能包含有多台Web前端服务器,用户的Http请求会被NLB机制分发到多台Web前端服务器的任意一台上。这就要求开发人员应该尽可能的编写出“无状态”的代码,也就是说,代码不能依赖于某一台具体的服务器,因为开发人员没有办法确定自己的代码会始终运行在一个服务器上。有可能一个用户浏览一个页面时,它的请求被分配到Web服务器A,然后当用户刷新一下页面,这次请求则被分配到了Web服务器B。
在这样的服务器场模型中,代码在服务器的内存里面保存的任何数据,都会随着下次用户刷新后,处理用户请求的服务器转移,而变得没有意义。这也是编写大规模分布应用代码的一个很典型的挑战。
当编写有可能运行在服务器场中的分布式应用时,通常都会引入一个专门的分布式数据存储或分布式缓存方案。比如说,有名的Memcached就是专门干这事儿的。
好吧,稍微扯远了一点。无论如何,SharePoint 2010由于某种原因,默认禁止在代码中使用Session。禁止的理由很可能是为了预防开发人员写出过于依赖Session的“有状态”代码,因为ASP.NET的Session默认是保存在服务器的内存中。一旦这些代码被部署到分布式服务器场环境中,它们就很可能由于依赖仅仅存储在某一台服务器内存中的Session数据而出错。
“你就别忽悠了,不要以为我们不知道ASP.NET的Session除了默认的InProc模式,还支持StateServer和SQLServer模式!”嗯,是的,ASP.NET的Session其实是可以配置成StateServer和SQLServer模式。StateServer模式是使用一台特定服务器上的一个Session State服务,来为服务器场中的所有服务器提供状态保存服务,SQLServer模式则是将所有状态信息保存到SQL Server数据库中。这两个模式都是能够很好的支持分布式服务器场模型的。
所以,对于喜欢在代码中使用Session的同学而言,我们可以大胆的通过修改Web应用程序的web.config文件,手工启用Session。不过,稍等,SharePoint 2010其实已经内置了一个PowerShell指令,让我们轻松的在服务器场里面启用Session。这个指令就是Enable-SPSessionStateService。
如上图所示,打开SharePoint 2010 Management Shell,输入如上指令,就可以在SharePoint配置数据库所在的SQL Server服务器上,自动创建一个名为“SharePoint_Session_State”的数据库,然后在所有Web应用程序的web.config中自动添加相应的条目。
这个自动添加的条目,指明了Session将使用SQLServer模式以及存放Session的数据库连接字符串。打开SQL Server Management Studio,就能找到这个由Enable-SPSessionStateService自动创建的数据库,它仅包含2个Table。
Enable-SPSessionStateService还提供了几个其他的参数。-DefaultProvision参数表示将直接使用SharePoint系统现有的配置数据库(默认就是SharePoint_Config)作为存放Session数据的数据库,而不再使用专门的数据库(我非常不推荐这个做法)。-DatabaseServer和-DatabaseCredentials则可以指定使用自定义的数据库服务器(而不是默认的放置配置数据库的那个服务器)和数据库连接帐户。
如果需要做一个反向操作,即在服务器场禁止Session的使用,可以使用Disable-SPSessionStateService指令。