session定义使用和丢失问题小结(20120101有更新&&20121026又更)
以前用Session的时候,总是拿来就用,也没想过先定义再使用,今天就换一种方式。
System.Web.SessionState.HttpSessionState session = System.Web.HttpContext.Current.Session;//创建Session
session.Add("admin","Test Session");//Session赋值
session.Timeout = 10;//设置会话超时期限,单位为分钟
Response.Write(System.Web.HttpContext.Current.Session["admin"].ToString());//测试成功
运行立刻可以可以知道结果了,否则,有时候session的值为null也不知道,还老是问为什么session不能传递到下一页面呢?为什么老是丢失呢?
然后在下一页面
protected void Page_Load(object sender, EventArgs e)
{
if (Session["admin"] == null)
{ Response.Redirect("login.aspx");
}
}就完成了登陆的session传递了和判断了
当然,用完了,例如注销登陆,则需要
Session["admin"] = "";//Session["admin"] = null 可理解 Session["admin"]根本不存在,但=""只不过说明他的值是 =""
Session .Abandon ();
结合我二次开发的blog这里有一点建议,如果调试不成功登陆可以考虑在登陆页面中的
if ( Session["admin"]== "loginok")
{
Response.Redirect("index.aspx");
}
代码不要,因为有可能session重复设置,导致混乱不清而出错。
我们在用C#开发程序的时候经常会遇到Session很不稳定,老是数据丢失。下面就是Session数据丢失的解决办法
1、在WEB.CONFIG文件中修改SESSION状态保存模式,如:
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="true" timeout="60"/>
说明:Web.Config文件中关于Session的设定如下 sessionState mode="inproc",所以要更改
2、启动系统服务“ASP.NET状态服务 ”,系统默认是手动启动的
3、如果SESSION中保存的数据类型是自定义的,如结构,请在自定义数据类型处序列化会话状态,即在类或结构申明前加[Serializable]
完成以上3部,状态即可保存,但是在访问页面是浏览器显示的路径中增加了一段字符,如:(S(lto3j0eg25cztmqtxevm5tb4))
SessionState 的Timeout),其主要原因有三种。
一:有些杀病毒软件会去扫描您的Web.Config文件,那时Session肯定掉,这是微软的说法。
二:程序内部里有让Session掉失的代码,及服务器内存不足产生的。
三:程序有框架页面和跨域情况。
第一种解决办法是:使杀病毒软件屏蔽扫描Web.Config文件(程序运行时自己也不要去编辑它)
第二种是检查代码有无Session.Abandon()之类的。
第三种是在Window服务中将ASP.NET State Service 启动。
又找到一篇文章,写是这样的
asp.net Session的实现
asp.net的Session是基于HttpModule技术做的,HttpModule可以在请求被处理之前,对请求进行状态控制,由于Session本身就是用来做状态维护的,因此用HttpModule做Session是再合适不过了。
原因1:
bin目录中的文件被改写,asp.net有一种机制,为了保证dll重新编译之后,系统正常运行,它会重新启动一次网站进程,这时就会导致Session丢失,所以如果有access数据库位于bin目录,或者有其他文件被系统改写,就会导致Session丢失
原因2:
文件夹选项中,如果没有打开“在单独的进程中打开文件夹窗口”,一旦新建一个窗口,系统可能认为是新的Session会话,而无法访问原来的Session,所以需要打开该选项,否则会导致Session丢失
原因3:
似乎大部分的Session丢失是客户端引起的,所以要从客户端下手,看看cookie有没有打开
原因4:
Session的时间设置是不是有问题,会不会因为超时造成丢失
原因5:
IE中的cookie数量限制(每个域20个cookie)可能导致session丢失
原因6:
使用web garden模式,且使用了InProc mode作为保存session的方式
解决丢失的经验
1. 判断是不是原因1造成的,可以在每次刷新页面的时候,跟踪bin中某个文件的修改时间
2. 做Session读写日志,每次读写Session都要记录下来,并且要记录SessionID、Session值、所在页面、当前函数、函数中的第几次Session操作,这样找丢失的原因会方便很多
3. 如果允许的话,建议使用state server或sql server保存session,这样不容易丢失
4. 在global.asa中加入代码记录Session的创建时间和结束时间,超时造成的Session丢失是可以在SessionEnd中记录下来的。
5. 如果有些代码中使用客户端脚本,如javascript维护Session状态,就要尝试调试脚本,是不是因为脚本错误引起Session丢失
哪些情况下该进程会重启动呢?微软的一篇文章告诉了我们:
1、配置文件中processModel标签的memoryLimit属性
2、Global.asax或者Web.config文件被更改
3、Bin文件夹中的Web程序(DLL)被修改
4、杀毒软件扫描了一些.config文件。
更多的信息请参考PRB: Session variables are lost intermittently in ASP.NET applications
解决办法:
前面说到的sessionState标签中mode属性可以有三个取值,除了InProc之外,还可以为StateServer、SQLServer。这两种存Session的方法都是进程外的,所以当aspnet_wp.exe重起的时候,不会影响到Session。
现在请将mode设定为StateServer。StateServer是本机的一个服务,可以在系统服务里看到服务名为ASP.NET State Service的服务,默认情况是不启动的。当我们设定mode为StateServer之后,请手工将该服务启动。
这样,我们就能利用本机的StateService来存储Session了,除非电脑重启或者StateService崩掉,否则Session是不会丢的(因Session超时被丢弃是正常的)。
除此之外,我们还可以将Session通过其他电脑的StateService来保存。具体的修改是这样的。同样还在sessionState标签中,有个stateConnectionString='tcpip=127.0.0.1:42424'属性,其中有个ip地址,默认为本机(127.0.0.1),你可以将其改成你所知的运行了StateService服务的电脑IP,这样就可以实现位于不同电脑上的Asp.net程序互通Session了。
如果你有更高的要求,需要在服务期重启时Session也不丢失,可以考虑将mode设定成SQLServer,同样需要修改sqlConnectionString属性。关于使用SQLServer保存Session的操作,请访问这里。
在使用StateServer或者SQLServer存储Session时,所有需要保存到Session的对象除了基本数据类型(默认的数据类型,如int、string等)外,都必须序列化。只需将[Serializable]标签放到要序列化的类前就可以了。
如:
[Serializable]
public class MyClass
{
......
}
总结的不是很有条理,还要慢慢消化.最要紧是思考,结合自己的实际情况检查,测试。
last总结:我写的blog系统
1、wed.config中的
<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" sqlConnectionString="data source=127.0.0.1;Trusted_Connection=yes" cookieless="true" timeout="60"/>
中,cookieless="true"是错的。应该是false, 或者删除,默认是false。
2、如果还不行,则检查数据库是否要写死,如相对路径该为绝对路径。
如:db类文件中
public string accessdb()
{
string path="provider=microsoft.jet.oledb.4.0;data source=" + Server.MapPath(@"App_Data\blog.mdb");
return path;
}
改为:string path="provider=microsoft.jet.oledb.4.0;data source=" + (@"d:\blog\App_Data\blog.mdb");
问题终于解决了,session丢失的机会基本上没有了,十次可能有一次,但已经算解决了,感谢佛山小西,猛男坚等人鼎力支持。
20110307在lingshan站点也修正了该问题,不过不需要把数据库路径写死.看来经验积累还是很有用的。
20120101开始,我写建站系统了..这时候发现有种写法.应该对上面情况更好解决..但没有在远程服务器上测试,...
就是这样写,以mdb为例
原来是
string path = "provider=microsoft.jet.oledb.4.0;data source=" + Server.MapPath(@"App_Data\blog.mdb");
改写为
string path = "provider=microsoft.jet.oledb.4.0;data source=" + System.Web.HttpContext.Current.Server.MapPath(@"App_Data\blog.mdb");
这样,就不怕系统找不到路径了,我认为这样写 才是最准确的,因为很严谨的啊....我之后会测试的了。
20121026更新:在专题网站中,一个完整的专题网站在本地机器测试,没有问题,在本地局域网内不同机测试,没有问题,放到远程服务器时候,系统显示还是没有问题,如果把它当做是一个站点,也没有问题....但是,当你把它设置为一个站点下的虚拟目录时候,问题出现了。就是登陆后台的时候,session丢失...啊!!!天啊。.怎么又遇到该问题呢.但在前面提及的情况是不存在的。为什么呢???我想了几天,一步步测试,response.write(session["ad"],终于,测试出来了,真的是到了验证时候,session丢失...我后来在if (HttpContext.Current.Session["ad"].ToString () != "ok"), 中加入ToString () ,问题却解决了.哈哈.真不可思议!可以登陆了,ok了。