现在的位置: 首页 > 综合 > 正文

在asp.net中使用session常见问题集锦

2013年10月12日 ⁄ 综合 ⁄ 共 8852字 ⁄ 字号 评论关闭

问:为什么session在有些机器上偶尔会丢失?  
答:可能和机器的环境有关系,比如:防火墙或者杀毒软件等,尝试关闭防火墙。  

问:为什么当调用session.abandon时并没有激发session_end方法?  
答:首先session_end方法只支持inproc(进程内的)类型的session。其次要激发session_end方法,必须存在session(即系统中已经使用session了),并且至少要完成一次请求(在这次请求中会调用该方法)。  

问:为什么当我在inproc模式下使用session会经常丢失?  
答:该问题通常是由于应用程序被回收导致的,因为当使用进程内session时,session是保存在aspnet_wp进程中,当该进程被回收session自然也就没有了,确定该进程是否被回收可以通过查看系统的事件查看器获得信息。  
 具体信息请参考:  
 session variables are lost intermittently in asp.net applications  
 
http://support.microsoft.com/default.aspx?scid=kb;en-us;q316148  
 在1.0的时候也有一个bug会导致工作进程被回收并重启,该bug已经在1.1和sp2中修复。  
 关于该bug的详细信息请参考:  
 asp.net worker process (aspnet_wp.exe) is recycled unexpectedly.   
 
http://support.microsoft.com/default.aspx?scid=kb;en-us;q321792  

问:为什么当session超时或者abandoned后,新session的id和原来的相同?  
答:因为sessionid是保存在客户端浏览器的实例里,当session超时在服务器重新建立session时,将使用浏览器传来的sessionid,所以当session超时后,再重新建立后sessionid并不变。  

问:为什么每次请求的sessionid都不相同?  
答:该问题可能是没有在session里面保存任何信息引起的,即程序中任何地方都没有使用session。当session中保存信息之后sessionid将一直和浏览器相关,此时的sessionid将不会在变化。  

问:asp和asp.net之间是否可以共享session?  
答:可以。但是这是一个比较复杂的过程,微软提供了官方的解决方案,请参考:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/converttoaspnet.asp  

问:什么类型的对象可以保存在session里?  
答:这依赖使用的session的模式,当使用的是进程内(inproc)的session那么可以轻松的保存任何对象。如果你使用了非inproc的模式,则只能保存可以序列化和反序列化的对象,如果此时保存的对象不支持序列化,则不能保存到这种模式(非inproc)的session里。  

问:为什么在session_end中不能使用response.redirect和server.transfer方法跳转页面?  
答:session_end是一个在服务器内部激发的事件处理函数。它是基于一个服务器内部的计时器的,在激发该事件时服务器上并没有相关的httprequest对象,因此此时并不能使用response.redirect和server.transfer方法。  

问:在session_end中是否可以获得httpcontext对象?  
答:不行,因为这个事件并没有和任何的请求(request)相关联,没有基于请求的上下文。  

问:在web service中该如何使用session?  
答:为了在web service中使用session,需要在web service的调用方做一些额外的工作,必须保存和存储调用web service时使用的cookie。详细信息请参考msdn文档的httpwebclientprotocol.cookiecontainer属性。然而,如果你使用代理服务器访问web service由于框架的限制,两者不能共享session。  

问:在自定义自己的httphandler的时候,为什么不能使用session?  
答:在实现自己的httphandler的时候,如果希望使用session必须实现下面的两个标记接口中的一个:irequiressessionstate和ireadonlysessionstate,这些接口没有任何方法需要实现,只是一个标记接口和使用inamingcontainer接口的方法一样。  

问:当我使用webfarm时,当我重定向到其他的web服务器时session为什么会丢失?  
答:详细信息请参考:  
 prb: session state is lost in web farm if you use sqlserver or stateserver session mode  
 
http://support.microsoft.com/default.aspx?scid=kb;en-us;325056  

问:为什么我的session在application_onacquirerequeststate方法中无效?  
答:session只有在httpapplication.acquirerequeststate事件调用以后才会有效。  
 详细信息请参考:  
 
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconhandlingpublicevents.asp   

问:如果使用了cookieless,我该如何从http页面定向到https?  
答:请尝试下面的方法:  
 string originalurl = "/fxtest3/sub/foo2.aspx";   
 string modifiedurl = "
https://localhost" + response.applyapppathmodifier(originalurl);   
 response.redirect(modifiedurl);  

问:session在global.asax中的那些事件中有效?  
答:session只有在acquirerequeststate事件之后有效,该事件之后的事件都可以使用session。  

问:如何获得当前session中保存的所有对象?  
答:可以通过遍历所有的session.keys来获得。代码如下:  
arraylist sessioncollection = new arraylist();  
foreach (string strkey in session.keys){   
  sessioncollection.add(session[strkey]);  
}   
   
问:是否可以在不同的应用程序中共享session?  
答:不能直接共享。可以参考如何在asp和asp.net之间共享session。  

问:session.abandon和session.clear有何不同?  
答:主要的不同之处在于当使用session.abandon时,会调用session_end方法(inproc模式下)。当下一个请求到来时将激发session_start方法。而session.clear只是清除session中的所有数据并不会中止该session,因此也不会调用那些方法。

 

问:为了可以顺序访问session的状态值,session是否提供了锁定机制?  
答:session实现了reader/writer的锁机制:  
 当页面对session具有可写功能(即页面有<%@ page enablesessionstate="true" %>标记),此时直到请求完成该页面的session持有一个写锁定。  
 当页面对session具有只读功能(即页面有<%@ page enablesessionstate="readonly" %>标记),此时知道请求完成该页面的session持有一个读锁定。  
 读锁定将阻塞一个写锁定;读锁定不会阻塞读锁定;写锁定将阻塞所有的读写锁定。这就是为什么两个框架中的同一个页面都去写同一个session时,其中一个要等待另一个(稍快的那个)完成后,才开始写。  

问:session平滑超时意味着什么?  
答:session平滑超时意味着只要你的页面访问(使用)了session,超时时间将被刷新(可以理解为重新计时),即从该页面请求开始,将重新计算超时时间。但是,该页面不能禁用session。它会自动的访问当前页面的session,刷新超时时间。  
   
问:在global.asax中的事件处理函数中session为什么无效?  
答:依赖于在哪个事件处理函数中使用session,session在acquirerequeststate事件之后才有效,该事件之后的所有事件处理函数都可以使用session,之前的则不能。  

问:当我写一个依赖于当前应用的session的组件时,为什么不能直接使用session["key"]获得其值?  
答:session["key"]实际上是this.session["key"],它是作为page的一个属性提供的,所以在你的组件中不能直接使用这个属性。你可以通过下面的方式使用session:  
 httpcontext.current.session["key"] = "my seesion value";   

问:当我使用inproc模式保存session时,此时的session是保存在哪里?  
答:不同的IIS的处理方式不同,  
 当使用的是iis5的时候session是保存在aspnet_wp.exe的进程空间里的。  
 当使用的是iis6时,默认情况下所有的应用程序共享应用程序池,session保存在w3wp.exe的进程空间中。  

问:session的超时设置是分钟还是秒?  
答:是分钟,默认为20分钟。  

问:当页面出现错误后我的session是否将被保存?我需要在session_end中处理一些清理工作,但是失败了,为什么?  
答:session_end只有在session运行在inproc模式下才会被执行。session_end使用的帐号是运行aspnet_wp工作进程的帐号(这个可以在machine.config中设置)。因此,如果在session_end方法里,使用集成安全性链接到sql,它将使用aspnet_wp进程的帐号打开链接,此时成功与否则依赖于你的sql的安全性设置。  
   
问:为什么当我设置cookieless为true是我在重定向的时候会丢失session?  
答:当使用cookieless时,你必须使用相对路径替换程序中的绝对路径,如果使用绝对路径asp.net将无法在url中保存sessionid。  
 例如:将/mydir/mysubdir/default.aspx换成../default.aspx即可。  

问:如何将sortedlist存储到session或者cache里?  
答:请参考下面的方法:  
 sortedlist x = new sortedlist();   
 x.add("key1", "valuea");   
 x.add("key2", "valueb");   
 保存到session中:   
 session["sortedlist1"] = x;   
 使用下面方法获得之:  
 sortedlist y = (sortedlist) session["sortedlist1"];   
 chahe则同理。  
   
问:我为什么会获得这样的错误信息“session state can only be used when enablesessionstate is set to true, either in a configuration file or in the page directive”?  
答:这个问题可能在一个已经安装了microsoft visual studio .net开发环境的机器上,再安装window sharepoint server(wss)后出现。  
 wss isapi过滤器会处理所有的请求。当你通过虚拟目录浏览一个asp.net的应用程序时,isapi过滤器不会给文件夹目录分配url。  
 解决方法是:不要再安装了wss的机器上使用session。  
 详细信息请参考:  
 session state cannot be used in asp.net with windows sharepoint services  
 
http://support.microsoft.com/default.aspx?scid=kb;en-us;837376  

问:如何删除session变量?  
答:想要删除session变量可以使用httpsessionstate.remove()方法。  
   
问:是否有办法知道应用程序的session在运行时占用了多少内存?  
答:没有。目前这个值时无法考证的,至少我现在还没有看到这方面的资料。但是可以通过性能监视器以及程序代码大概估算出来一个值。  
   
问:当页面中是否了frameset,发现在每个frame中显示页面的sessionid在第一次请求时都不相同,为什么?  
答:原因是你的frameset是放在一个htm页面上而不是aspx页面。  
 在一般情况下,如果frameset是aspx页面,当你请求页面时,它首先将请求发送到web服务器,此时已经获得了sessionid,接着浏览器会分别请求frame中的其他页面,这样所有页面的sessionid就是一样的,就是frameset页面的sessionid。  
 然而如果你使用html页面做frameset页面,第一个请求将是html页面,当该页面从服务器上返回是并没有任何session产生,接着浏览器会请求frame里面的页面,这样这些页面都会产生自己的sessionid,所以在这种情况下就会出现这种问题。当你重新刷新页面时,sessionid就会一样,并且是最后一个请求页面的sessionid。  
   
问:是否可以将不同应用程序的session保存在相同的sql server服务器的不同数据库上。  
答:可以,请参考:  
 fix: using one sql database for all applications for sql server session state may cause a bottleneck  
 
http://support.microsoft.com/default.aspx?scid=kb;en-us;836680 

 

问:在session_end是我是否可以获得有效的httpsessionstate和httpcontext对象?  
答:你可以在这个方法中获得httpsessionstate对象,可以直接使用session来访问即可。但是不能获得httpcontext对象,因为该事件并没有和任何请求相关联,因此不存在上下文对象。  

问:在sqlserver模式下使用session,为什么我的session不过期?  
答:在sqlserver模式下,session的过期是通过sql agent的注册工作完成的,请检查你的sql agent是否运行?  
   
问:当我设置enablesessionstate为“readonly”后,但是我在inproc模式下依然可以修改session的值,这是为什么?  
答:即使enablesessionstate标示为readonly,但是在inproc模式下用户依然可以编辑session。唯一不同的是,在请求过程中session将不会被锁住。  

问:我如何才能避免在链接sql时指定密码?  
答:使用信任链接或者使用加密的链接串。有关这方面的详细信息请参考:  
 how to use the asp.net utility to encrypt credentials and session state connection strings   
 
http://support.microsoft.com/default.aspx?scid=kb;en-us;329290  

问:我在我自己的类中该如何使用session呢?  
答:可以使用httpcontext.current.session方式使用,具体方法如下:  
 httpcontext.current.session["sessionkey"] = "sessionvalue";   
 类似的你还可以使用这种方式使用application对象。  
   

问:为什么在切换成sqlserver模式后我的请求被挂起了?  
答:检查在session里面是否都保存的是可以保存在sqlserver模式下的对象,即这些对象必须支持序列化。  
   

问:当session设置成cookieless后会有什么影响?  
答:当把cookieless设置成true时,主要会有下面的约束:  
 1、在页面中不能使用绝对链接  
 2、在应用程序中在除了http和https之间的切换时需要完成一些其他的步骤。  
 如果发送一个链接给其他人,此时的url里面将包含session id的信息,所以两个人将公用一个session。  

问:是否可以将session保存在数据库中?  
答:当然可以,详细信息请参考:
http://support.microsoft.com/default.aspx?scid=kb;en-us;311209   

----------------------------------------------------------------------------------------------------------------------  
问:为什么当我在inproc模式下使用session会经常丢失?  
补充一种情况:如果使用access数据库,为了防止数据库被下载,有人可能会想到会把数据库文件放到bin目录下,这样数据库就不能被下载了,但是如果在inproc模式下,这样也会导致session丢失。因为当访问应用程序的时候,肯定会经常向数据库中写数据,这样就导致了放在bin目录下面数据库文件的变化,而bin目录被修改会导致session丢失。  
要解决此问题,可以更换数据库文件的存放路径,或者使用stateserver或者sqlserver模式。  
更多情况请参考:  
prb: session data is lost when you use asp.net inproc session state mode  
http://support.microsoft.com/default.aspx?scid=kb;en-us;324772  
-------------------------------------------------------------------------  
asp.net中多项目共享session     选择自 dnyz 的 blog   
http://dev.csdn.net/article/21/21714.shtm  
1.         建立一个空白解决方案blank solution,如:d:/myproject/myproject.sln  
2.         在d:/myproject下建一个web application的根目录d:/myproject/webmis并设为
http://localhost/webmis的虚拟目录  
3.         在webmis目录下根据模块分别新建目录,如:d:/myproject/webmis/login和d:/myproject/webmis/checkout  
4.         在vs.net中根据模块新建web application,如:
http://localhost/webmis/loginhttp://localhost/webmis/checkout   
5.         新建后login和checkout两个目录自动被设置为虚拟目录  
6.  在webmis项目中添加login和checkout的项目引用  
7.在iis管理器中删除login和checkout的虚拟目录  
8.         删除各项目的global.asax(除根项目)  
9.         除去个项目的web.config(除根项目)中的如下代码:  
<authentication mode="windows" />  
<sessionstate mode="inproc" stateconnectionstring="tcpip=127.0.0.1:42424" sqlconnectionstring="data source=127.0.0.1;trusted_connection=yes" cookieless="false" timeout="20" />  
或删掉web.config(若不需要在各目录中进行配置)  
10.         编译后,即可运行。

抱歉!评论已关闭.