原文链接:http://www.cnblogs.com/fish-li/archive/2013/05/28/3104750.html

Session与复杂数据类型

Session有三种工作模式,拿ASPX页面来说,EnableSessionState指令有三个可选值:true, false, ReadOnly

第一个

EnableSessionState="false",这个容易理解:不使用Session。

第二个

EnableSessionState="ReadOnly",从字面上来说,就是Session是只读的。

只读的控件不允许用户修改,然而Session的只读模式是说:你可以改,但我不保存你的修改。 这样理解没有问题吧。

第三个

EnableSessionState="true",表示Session支持可读可写。

当你更新了Session的内容之后,当前会话的所有Session数据将会被重新保存。

进程内Session容易丢失,且不支持多台Web服务器共享数据,因此选择这种保存方法的人不多, 大多数人会选择状态服务或者SQL Server来保存,那么这里就有一个问题需要关注了: 当Session模式是EnableSessionState="true"时,如果你访问了一个复杂对象(不是系统值类型也不是字符串), 不管你有没有修改它,Session的保存操作都会执行。 对于进程外Session,保存操作意味着需要执行序列化,还可以会有网络传输的开销,它们会影响性能。

如果上面的描述不容易理解的话,请看下面的示例代码:

string sessionValue = Session["s2"] as string;
if( sessionValue == null ) {
Session["s2"] = "Fish Li";
sessionValue = Session["s2"] as string;
}

当这个页面首次运行时,Session被修改了,因此会有保存的操作发生。但是后面的访问就不会有保存的动作。

再看另一段代码:

// TestData是一个自定义类型。
TestData sessionValue = Session["s1"] as TestData;
if( sessionValue == null ) {
Session["s1"] = new TestData { IntValue = 5, StrValue = "Fish Li" };
sessionValue = Session["s1"] as TestData;
}

此时每次执行这段代码时,都会有保存操作发生(只要是EnableSessionState="true")。

我再重申一遍:这个问题只有当EnableSessionState="true",且访问复杂对象(不是系统值类型也不是字符串)才会发生。 对于进程内Session来说,这个问题的影响不大,但是对于进程外Session来说,会对性能产生一些影响, 到底有多大的影响,要根据Session的数据量以及用户的并发度来决定。

列出这个问题只是想告诉大家:如果你确实需要使用Session,请尽量在Session中保存【不可变】的简单数据, 尤其是不要保持Session的默认设置(EnableSessionState="true")。

检验这个问题的方法是:实现一个自定义的SessionStateStoreProviderBase派生类,然后调试观察。 SessionStateItemCollection的二个索引器也会给你一个答案。

引申一下服务器端的Session管理,web form做例子

web form网页是基于HTTP的,它们没有状态, 这意味着它们不知道所有的请求是否来自 同一台客户端计算机,网页是受到了破坏,以及是否得到了刷新,这样就可能造成信息的 丢失。于是,状态管理就成了开发网络应用程序的一个实实在在的问题。在ASP中能够通过Cookie 、查询字符串、 应用程序、会话(Session) 等轻易解决这些问题。 现在在ASP.NET环境中,我们依然可以使用这些功能,并且功能更加强大。

状态管理分为服务端和客户端两种情况, 这里只是介绍 服务端状态管理:

与Application对象不同的是, ASP.NET 的Session对象可以在IIS服务器或者工作进程重新启动时 恢复启动前的状态而不丢失其中的数据。这是因为存储在Session中的所以信息都缺省的存储在 一个作为Windows服务运行的状态服务器进程中。状态可以被序列化并以二进制形式保存在内存中。 程序员可以悬着使用Microsoft Sql server数据库来存储数据。

状态服务器服务和状态信息可以和web应用程序一起存在于同一台服务器上,也可以保存到外部的 状态服务器上。 为了指定如何存储信息,程序员可以在web.config文件中编写适当的配置。

ASP.NET会话状态模块在Web.config文件中<System.web>标记下的标记的mode属性来决定 该属性的四种可能的值:** Off、 Inproc StateServer 和SQLserver**。

1 Inproc是缺省的设置

它允许“无Cookie”的会话,以及在服务器之外存储 会话数据。ASP.NET会话状态模块在Web.config文件中像下面这样配置:

<sessionState mode="InProc" cookieless="false" timeout="20" />

在这个例子中,mode属性设为InProc(默认值),表明会话状态要由ASP.NET存储到内存中,而且 不用Cookie来传递会话ID。相反,会话ID要直接插入一个网页URL的查询字符串中。例如,采用 InProc模式并建立一个会话之后,调用一个假想的ASP.NET网页时,需要采用下面这样的URL:

http://my.website.com/(12mfju55vgblubjlwsi4dgjq)/education.aspx

圆括号中长长的字母、数字字符串12mfju55vgblubjlwsi4dgjq就是会话ID。ASP.NET引擎从查询字符中提取会话ID,并将用户 请求与特定会话联系起来。采取这种方式,不管Cookie还是隐藏表单字段都用不着了。 所以,即使网页中没有使用表单,也能加入会话。

但是这种方法,应用程序的状态将依赖于 ASP.NET进程, 当IIS进程崩溃或者正常重启时,保存在 进程中的状态将丢失。

2 mode属性设为Off

和从前的ASP一样,ASP.NET的会话状态管理是要产生开销的。所以,假如某个网页不需要访问 Session对象,开发者应将那个页的Page预编译指令的EnableSessionState属性设为False。 要为整个网站禁用会话状态,可在Web.config文件中将sessionState元素的mode属性设为Off。

为了克服inproc 模式的缺点, ASP.NET 提供了两种进程外保存会话状态的方法。

3 StateServer会话管理

将mode属性设为StateServer,也就是将会话数据存储到单独的内存缓冲区中,再由单独一台机器上运行

的Windows服务来控制这个缓冲区。状态服务全称是“ASP.NET State Service ”(aspnet_state.exe),

它由Web.config文件中的stateConnectionString属性来配置。该属性指定了服务所在的服务器,以及要监视的端口: 在这个例子中,状态服务在一台名为myserver的机器的42424端口(默认端口)运行。要在服务器上改变端口,可编辑HKLM\SYSTEM\CurrentControlSet\Services\aspnet_state注册表项中的Port值。

显然,使用状态服务的优点在于进程隔离,并可在Web form中共享。 使用这种模式,会话状态的存储将不依赖于iis进程的失败或者重启,然而,一旦状态服务中止,所有会话数据都会丢失。换言之,状态服务不像SQL Server那样能持久存储数据;它只是将数据存储在内存中。

4 用SQL Server进行会话管理

ASP.NET还允许将会话数据存储到一个数据库服务器中,方法是将mode属性变成SqlServer。 在这种情况下,ASP.NET尝试将会话数据存储到由sqlConnectionString属性(其中包含数据源以及登录服

务器所需的安全凭证)指定的SQL Server中。 为了用恰当的数据库对象来配置SQL erver,管理员还需要创建ASPState数据库, 方法是运行WinDir\Microsoft.Net\Framework\Version文件夹中的InstallState.sql脚本(WinDir是服务

器的Windows文件夹,而Version是你使用的.NET框架版本的安装文件夹)这个脚本文件我没有找到,等做这个功能的时候再处理这个问题。 要配置SQL服务器,可以在命令行中运行SQL Server 提供的命令行工具osql.exe

osql -S [ server name] -U [user] -P [password] <InstallSqlState.sql 例如 osql -S (local)\NetSDK -U sa -P "" -i InstallSqlState.sql

在这里用户名必须是SQL服务器上的sa帐号,或者具有同等权限的其他帐号。有兴趣的读者可以打开 这个脚本文件来了解ASP.NET是如何和SQL Server配合实现状态管理的。

卸载这些表和存储过程,可以使用UninstallSqlState.sql脚本,使用方法与上面类似。

做好必要的数据库准备工作后,将web.config 文件中的sessionstate 元素的mode改为"sqlserver" ,并且指定SQL连接字符串。具体如下:

mode="sqlserver" sqlConnectionString="data source=127.0.0.1; userid=sa; password="

配置好SQL Server后,应用程序代码运行时就和InProc模式没有什么区别。但要注意的是,由于数据不存

储在本地内存,所以存储会话状态的对象需要进行序列化和反序列化,以便通过网络传给数据库服务器,

以及从数据库服务器传回。这当然会影响性能。通过在数据库中存储会话状态,可分别针对扩展性及可靠

性来有效地平衡性能。另外,可以利用SQL Server的集群,使状态存储不依赖于单个的SQL Server, 这样就可以为应用程序提供极大限度的可靠性。

ASP.NET-Session与复杂数据类型的更多相关文章

  1. ASP.NET Session丢失的情况

    正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. 现在我就把原 ...

  2. ASP.NET Session丢失的解决方案

    正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的.现在我就把原因 ...

  3. ASP.NET Session丢失问题原因及解决方案

    正常操作情况下会有ASP.NET Session丢失的情况出现.因为程序是在不停的被操作,排除Session超时的可能.另外,Session超时时间被设定成60分钟,不会这么快就超时的. ASP.NE ...

  4. asp.net session丢失的解决方法小结

    现在我就把原因和解决办法写出来. ASP.NET Session丢失原因: 由于Asp.net程序是默认配置,所以Web.Config文件中关于Session的设定如下: < sessionSt ...

  5. ASP.NET Session原理及处理方法

    session是怎么存储,提取的 1.在服务器端有一个session池,用来存储每个用户提交session中的数据,Session对于每一个客户端(或者说浏览器实例)是“人手一份”,用户首次与Web服 ...

  6. ASP.net session丢失

    ASP.NET Session的实现: asp.net的Session是基于HttpModule技术做的,HttpModule可以在请求被处理之前,对请求进行状态控制,由于Session本身就是用来做 ...

  7. ASP.NET Session 详解

    阅读本文章之前的准备 阅读本文章前,需要读者对以下知识有所了解.否则,阅读过程中会在相应的内容上遇到不同程度的问题. 懂得ASP/ASP.NET编程 了解ASP/ASP.NET的Session模型 了 ...

  8. ASP.NET Session的共享

    注: 在ashx文件中使用Session 首先添加引用 using System.Web.SessionState; 实现接口 public class XXXX: IHttpHandler ==&g ...

  9. 使用SQL Server存储ASP.NET Session变量

    创建和配置ASP.NET Session状态数据库 在基于NLB(网络负载平衡)环境下的ASP.NET Web应用程序开发,我们需要将Session存储在数据库中供多个Web应用程序调用,以下为配置方 ...

  10. ASP.NET Session的七点认识

    原文:http://kb.cnblogs.com/page/108689/ ASP.NET Session的使用当中我们会遇到很多的问题,那么这里我们来谈下经常出现的一些常用ASP.NET Sessi ...

随机推荐

  1. R语言的帮助使用和图形功能简单介绍

    R语言的帮助使用和图形功能简单介绍 R语言帮助,在Windows桌面下,有很多种.最长使用的是在命令行下help() > help.start() 会在浏览器中,打开帮助的主页 watermar ...

  2. How to remove focus without setting focus to another control?

    How to remove focus without setting focus to another control? Ask Question up vote 67 down vote favo ...

  3. zzulioj--1613--少活一年?(稍微有点坑,水!)

    1613: 少活一年? Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 344  Solved: 70 SubmitStatusWeb Board De ...

  4. 32.QT绘图

    widget.h #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QPainter> #inclu ...

  5. spring《四》自动装配

    byName模式<bean autowire="byName"> Spring会查找一个叫做date的bean定义. byType模式<bean autowire ...

  6. User_Login_Register_Shopping 1.0

    #!/usr/bin/env python# -*- coding: utf-8 -*-# @File : user_login_register_shopping.py# @Author: Anth ...

  7. EntityFramework使用及优化

    1. 简介 ORM框架:Object Relation Mapping,用操作对象的方式来操作数据库 其它框架:Dapper.NHibernate,首推EF,微软官方的. EF底层还是ADO.NET实 ...

  8. ubuntu16.04 安装 docker-compose

    下载安装 docker-composecurl -L https://github.com/docker/compose/releases/download/1.15.0/docker-compose ...

  9. 查看md文件

    使用命令将md文件转为html,在浏览器中演示 通过npm安装i5ting_toc 安装好node之后,可以直接使用npm.Windows+R打开运行框,输入cmd,打开命令窗口.连网的情况下,输入如 ...

  10. mysql case when then 使用

    建表:create table hank (id int,name varchar(20)); 插入数据:insert into hank values(1,'A');insert into hank ...