本文的目的在于提供一种可行的解决方案通过Web Service技术来整合和管理现有的Asp程序到Asp.Net。 此应用解决方案尽可能从实际出发以迭代更新方式的策略把Asp Web服务器内存中的当前Session更新到Asp.Net。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
背景: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
  现有公司的产品OA是采用asp早先的技术开发,需要与目前最新的asp.net产品进行数据交互的应用。现有的asp应用程序 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
往往采用“ASP sessions”,这是一种经典的asp内置模式,即允许数据临时暂存在web服务器内存中,其最大的限制因素就 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
是asp的session状态是依赖具体的服务器。而另一个更宽范围的解决方案就是很多web服务器都可能别用于根据请求而指向的 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
任何网络服务器。实际上就是所有的web服务器都像在一个农场中,因而任何在内存中的session状态将不会自动跟随请求。每 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
个asp服务器提供自己的session状态,除非用户很凑巧的返回统一服务器,造成系统session丢失。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      通过使用服务器管理产品(如bigip)来强制用户会同意服务器内的web农场来解决内存中asp seesion因服务器关系而造 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
成的问题。为了达到这个目的,采用一个cookie在客户端工作,在服务器端来使用,让用户直接可以回到同一个服务器上的 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
每个reqeust。这样可以限制扩展性,提高可维护性,避免服务器故障的风险(例如:session丢失服务器 失败)。–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
     微软Asp.net技术的出现终于解决了这个问题,可以让我们来存储session信息到web server和database或者其他域 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
server。不错,问题解决了,我们还有必要用asp代码吗?全部扔掉?如果这样做的话就会需要很大代价去重新使用.net来 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
重写asp。看来还是不可行。另一种比较好的解决方案就是用迭代方法来部分移植代码到新的模型胜过重写asp代码,在这 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
个过程中如果旧的ASP代码和新的asp.net代码可以有一个共同的session状态而保持正常的工作,那么在整个生命周期中 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
将会有益于你更好的规避风险.以下提供了几个解决方案从此略上来解决当采用经典的asp sesssion因服务器关系而造成的 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
问题。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
1、用户自定义组或者使用Asp/ADO脚本去实现直接读写用户session数据到数据库; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
2、用户自定义组件去直接访问asp.net seesion数据; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
3、通过web servieces建立asp到asp.net的桥共享session;  –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
  在本文中,我们将讨论最后一种方案,其中也会包括一些web services与asp/ADO定制数据库,和asp session 池的基本 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
性能数据比较,呵呵...看完后你自己选择用哪个。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
ASP to ASP.NET Bridge / Web-Service 方案 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
此方案中只是简单的实现了一个从asp到asp.net的web services桥梁,如果你需要用数据库,只需要进行简单的配置(web. –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
congfig和aspState 数据库)。代码中用来获得和设置session数据的方法写在一个javascirpt中,该文件必须保存在本地asp –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
程序中。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
此javascirpt实现MSXML, http功能以便和server端交互,并负责将这些cookie回收给用户工作站。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
优点: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
  支持与服务器无关的web-farm部署,提高可扩展性简单的实现asp和asp.net的共同session状态松耦合,以sessioni管理 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
(无连接的HTTP接口, 80端口,可防火墙等)利用久经时间考验的asp.net session实施。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
缺点: 比asp session 内存池实现和数据库实现会慢。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Asp内存共享机制: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Session是采用类似字典或者哈希表的形势保存在web server内存中,ASP会保持session状态,提过一个特别的key给 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
用户,当session会话开始时,这个key将保存cookie来纪录客户端发送到服务器的每一项请求,在服务器端,获得cookie –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
的key,就可以知道request对应的session.这种机制的一个明显的优势就是速度和方便,所有的session都会在一台服务器上 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
保存,所以很开,但是正如前面所说的,将数据保存在一台服务器也是一个重大缺点,迫使用户返回同一台服务器检索 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
session数据。这个减少了webform的优势,它只是一种低成本,大淘汰的策略,如果你只想实现简单功能,就可以用它。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
优点: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
        内存纪录seesion,速度快,使用标准的ASP代码基础利用久经时间考验的ASP session实施。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
缺点: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
        它承载的能力有限,无法大规模开展网络农场(服务器依赖度高) ,服务器故障导致session丢失,内存占有率太大。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Asp/ADO数据库实现解决方案 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      建立了一个数据库连接之间的ASP应用服务器和数据库服务器。使数据被存在一个中央数据库或者数据库集群,然后分 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
别从不同的服务器上的asp程序执行。本文种只给出方案。获取和设置session的代码可以被放进一个javascirpt文件中,支 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
持基于webservices获取的方法,允许asp取代javascirpt定制数据库模式,直接访问asp.netsession数据(如建立aspstate –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
数据库)。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
优点: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      1、支持不依赖服务器的webform部署; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      2、比asp.net Web服务更快; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
缺点: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      1、代码为定制执行(比较死板); –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      2、比内存共享ASP sessions 慢; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      3、需要数据库连接,从网络服务器到数据库服务器; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
性能: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
      在下面数据中,列出了每种方案的性能比较,强调的是内存共享aspsession池最快小型用户可以使用,采用数据库的话 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
也会增加额外的开支,增加成本(除非你很有钱)。减 少网络回传,服务器请求是提高性能的唯一方法,微软的Web应用程 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
序压力工具,是用来执行测试压力水平的25个线程为1分钟的时间从表中可以明显的看出用内存存储aspsession比另外两种方 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
式更快。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Method Get Data (ms) Set Data (ms)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
5 values 1 value 5 values 1 value–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
In-memory ASP Sessions 46 9 34 7–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
ASP/ASP.NET web service individually 4321 864 3397 679–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
ASP/ASP.NET web service grouped 711 142 990 198–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
ASP/ADO database individually 346 69 841 168–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
ASP/ADO database grouped 163 33 860 172 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
代码描述ASP机制,在asp中创建sessioni 如下: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Session("Sky") = "Blue";–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
在其他的页面中访问这些值采用:–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var skyString = Session("Sky"); –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
新的API语法: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
下面的语法将会代替原来的asp session 语法,目的是在桥的使用中javascript 函数可以进行封装–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
设置一个关键值对;–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
设置一个kye-value 类型session 数据,语法和值钱的asp Session 语法很相似,采用下面的代码可以把现有的设置asp session代码替换; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
设置sessioni数据:–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
SetSessionValue("Sky", "Blue");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
获取 session : –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var SkyString = GetSessionValue("Sky");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
这种方法建议在设置比较少的情况下用–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
设置多个key-valus对值–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
这些方法的最大开销在于设置每一个key-value,然后返回给webservice,推荐用以下方法来设置(当超过3对以上的key-values)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
设置session–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var sessionInfo = NewSession();–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
sessionInfo.Add(“Sky”, "Blue");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
sessionInfo.Add(“Grass”, “Green”);–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
SetSession(sessionInfo); –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
获得session–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var sessionInfo = GetSession();–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var skyString = sessionInfo.Item(“Sky”);–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var grassString = sessionInfo.Item(“Grass”);–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Java Script Example–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<%@ Language="JScript" %> –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<script language="JScript" runat="server" src="ASPSessionWS.js" /> –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<%–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    var sessionInfo = NewSession();–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    sessionInfo.Item("Sky") = "Blue";–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    sessionInfo.Item("Grass") = "Green";–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    SetSession(sessionInfo);                –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    var retrievedSession = GetSession();–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    var sSky = retrievedSession.Item("Sky");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    var sGrass = retrievedSession.Item("Grass"); –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Response.Write(sSky + "<br>");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Response.Write(sGrass + "<br>");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
%> –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Visual BASIC Example–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<%@ Language="VBSCRIPT" %> –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<script language="JScript" runat="server" src="ASPSession.js" /> –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<%–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Dim sessionInfo        –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Set sessionInfo = NewSession()–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    sessionInfo.Item("Sky") = "Blue"–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    sessionInfo.Item("Grass") = "Green"–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    SetSession(sessionInfo)                –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Dim retrievedSession–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Set retrievedSession = GetSession()–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Dim sSky–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    sSky = retrievedSession.Item("Sky")–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Dim sGrass–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    sGrass = retrievedSession.Item("Grass") –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Response.Write(sSky & "<br>")–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    Response.Write(sGrass & "<br>")–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
%> –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Web Service 实现代码 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
此webservice有4个简单方法组成,它支持再asp.net sessioni中设置和获得单独的values,以及简化通过装载xml来设置 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
session变量的复杂度。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
public string getSessionValue(string sessionVariable)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
public bool setSessionValue(string sessionVariable, string sessionValue)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
public string getSessionValues()–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
public bool setSessionValues(string xmlSessionValues)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
为了让asp.net web service能够来支持创建和维护sessions,要通过下面包含在每个方法中的属性,这将返回一个asp.net_ –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
sessionID的cookie到响应中可以作为使用asp Session代码的桥。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
[WebMethod(EnableSession=true)] –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
你也可以增加很多webservices接口来实现其他你想要的功能。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
ASP 桥的实现: –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Asp端的桥,其实就是一个依赖msxml2.serverXMLhttp COM接口为访问web services的服务端和Scripting.Dictionary 提 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
供一个哈希表。在当前页中保持一个临时的副本session. –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var xmlHTTP = Server.CreateObject("MSXML2.ServerXMLHTTP");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
xmlHTTP.open("POST", sURL, false);    –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var clientCookie = "" + Request.Cookies("ASP.NET_SessionId");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
xmlHTTP.setRequestHeader("cookie", "ASP.NET_SessionId=" + –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
  clientCookie + "; path=/;");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
.–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
.–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
.–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
Response.Cookies("ASP.NET_SessionId") = httpCookie;–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
字典对象转化–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var dctSession = new ActiveXObject("Scripting.Dictionary");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
var re = new RegExp("<SessionItem ", "g");–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
部署–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
文件aspseesionws.js必须放在asp程序下,并且在asp.net程序中写上如下代码–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
<script language="”Jscript”" runat="”server”" src=”\Script\ASPSessionWS.js” >–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
</script>–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
采用80端口访问web server,在脚本文件中写如下函数,用来维护session状态–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
function GetWebService(Function, Parameters)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
{–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    var xmlPayload = "";–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
    var sURL = "http://www.xxxx.com/ASPBridge/bridge.asmx" + "/" + –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
        Function; –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
总之,采用webservice 建立从遗留的asp session 到新的asp.net 的session,只要的目的是为了采用新的技术整合旧的程序, –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
允许2个程序共享一个session内容,虽然性能很重要,但是目前还没有更完美的方法完全的把原有程序整合进.net。 –þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß
示例下载:ASPBridge.rar (5.59 kb)–þÂYlåú]www.netcsharp.cnOÕ52 ÿúrß