王朝网络
分享
 
 
 

在ASP与ASP.NET之间共享对话状态(1)

王朝asp·作者佚名  2008-05-19
宽屏版  字体: |||超大  

前言:

ASP.NET是微软提供的最新的开发基于Web的应用程序的技术。它提供了大量的比传统ASP脚本技术的好处,包括:

1)通过把UI表现层(presentation)与商业逻辑(business logic)分开建立了更好的开发结构;

2)使用完全编译的代码代替了传统ASP的代码翻译;

3)它编译特性与每个支持的方法协同,这意味着使用ASP.NET的站点比使用传统的ASP站点的性能更高。

尽管把存在的ASP应用程序转换到ASP.NET有很多潜在的好处,也有些ASP应用程序任务很重要并且复杂。转换过程可能需要更多资源并给应用程序带来更多风险。解决这些问题的途径之一是同时运行ASP和ASP.NET应用程序,在一个时刻将一个对话转换为ASP.NET。为了同时运行新旧程序,需要建立一个机制在传统的ASP与ASP.NET间共享对话状态。本文讨论的是怎样使用.NET框架组件的类和序列化特性共享状态信息。

概述

Cookie是Web应用程序识别用户对话的最常用的方法,可以用于识别传统的ASP和ASP.NET对话状态。在ASP脚本中状态信息保存在内存中,不能与其它应用程序(例如ASP.NET)共享。如果对话状态使用通用格式保存在微软SQL Server中,它就可以被传统的ASP和ASP.NET共同访问。

在本例中,名为mySession的Cookie用于识别用户对话。当用户对Web应用程序作出请求时,将为该用户产生唯一的Cookie用于识别对话。在随后的请求中,浏览器将该唯一的Cookie发送回服务器用来识别对话。在被请求的Web页载入前,一个自定义对象将使用该唯一的Cookie从SQL Server中重新载入用户对话数据。通过自定义对象Web页中的对话状态是可以访问的。Web请求完成后,如果请求终止,对话数据将保存回SQL Server(见图1)。

图1.数据流简单图

ASP.NET实现

在ASP.NET中每一个Web页都衍生自System.Web.UI.Page类。Page类集合了HttpSession对象的一个实例用于处理对话数据。在本例中,叫做SessionPage的自定义Page类来衍生自System.Web.UI.Page,提供了类似Page类的所有特性。唯一的区别是默认的HttpSession使用自定义的对话对象重载了(对实例变量使用new修改符,C#允许衍生的类隐藏基类的成员)。

public class SessionPage : System.Web.UI.Page

{

...

public new mySession Session = null;

...

}

自定义的对话类使用HybridDictionary对象来相应保存内存中的对话状态(HybridDictionary可用于处理任意数量的对话元素)。为了与传统的ASP通用,该自定义对话对象将限制对话数据类型为字符串型(默认的HttpSession允许对话保存任意类型的数据,不能与传统的ASP通用)。

[Serializable]

public class mySession

{

private HybridDictionary dic = new HybridDictionary();

public mySession()

{

}

public string this [string name]

{

get

{

return (string)dic[name.ToLower()];

}

set

{

dic[name.ToLower()] = value;

}

}

}

Page类为定制暴露了不同的事件和方法。特别是OnInit方法用于设置Page对象的初始化状态。如果请求不包含名为mySession的Cookie,将为请求者产生一个新的mySession Cookie。另外,对话数据将使用自定义数据访问对象SessionPersistence从SQL Server中检索出来。DSN和SessionExpiration的值从web.config中检索。

override protected void OnInit(EventArgs e)

{

InitializeComponent();

base.OnInit(e);

}

private void InitializeComponent()

{

cookie = this.Request.Cookies[sessionPersistence.SessionID];

if (cookie == null)

{

Session = new mySession();

CreateNewSessionCookie();

IsNewSession = true;

}

else

Session = sessionPersistence.LoadSession(

Server.UrlDecode(cookie.Value).ToLower().Trim(),

dsn,

SessionExpiration

);

this.Unload += new EventHandler(this.PersistSession);

}

private void CreateNewSessionCookie()

{

cookie = new HttpCookie(sessionPersistence.SessionID,

sessionPersistence.GenerateKey());

this.Response.Cookies.Add(cookie);

}

SessionPersistence类使用微软.NET框架组件的BinaryFormatter来串行化和并行化对话状态为二进制格式以提供最佳性能。结果的二进制对话数据接着作为图象字段类型被存入SQL Server。

public mySession LoadSession(string key, string dsn,

int SessionExpiration)

{

SqlConnection conn = new SqlConnection(dsn);

SqlCommand LoadCmd = new SqlCommand();

LoadCmd.CommandText = command;

LoadCmd.Connection = conn;

SqlDataReader reader = null;

mySession Session = null;

try

{

LoadCmd.Parameters.Add("@ID", new Guid(key));

conn.Open();

reader = LoadCmd.ExecuteReader();

if (reader.Read())

{

DateTime LastAccessed =reader.GetDateTime(1).AddMinutes(SessionExpiration);

if (LastAccessed = DateTime.Now)

Session = Deserialize((Byte[])reader["Data"]);

}

}

finally

{

if (reader != null)

reader.Close();

if (conn != null)

conn.Close();

}

return Session;

}

private mySession Deserialize(Byte[] state)

{

if (state == null) return null;

mySession Session = null;

Stream stream = null;

try

{

stream = new MemoryStream();

stream.Write(state, 0, state.Length);

stream.Position = 0;

IFormatter formatter = new BinaryFormatter();

Session = (mySession)formatter.Deserialize(stream);

}

finally

{

if (stream != null)

stream.Close();

}

return Session;

}

在请求的末尾,Page类的Unload事件被启动了,一个同Unload事件一起注册的事件处理方法将串行化对话数据为二进制格式并将结果二进制数据存入SQL Server。

private void PersistSession(Object obj, System.EventArgs arg)

{ sessionPersistence.SaveSession(

Server.UrlDecode(cookie.Value).ToLower().Trim(), dsn, Session, IsNewSession);

}

public void SaveSession(string key, string dsn,

mySession Session, bool IsNewSession)

{

SqlConnection conn = new SqlConnection(dsn);

SqlCommand SaveCmd = new SqlCommand();

SaveCmd.Connection = conn;

try

{

if (IsNewSession)

SaveCmd.CommandText = InsertStatement;

else

SaveCmd.CommandText = UpdateStatement;

SaveCmd.Parameters.Add("@ID", new Guid(key));

SaveCmd.Parameters.Add("@Data", Serialize(Session));

SaveCmd.Parameters.Add("@LastAccessed", DateTime.Now.ToString());

conn.Open();

SaveCmd.ExecuteNonQuery();

}

finally

{

if (conn != null)

conn.Close();

}

}

private Byte[] Serialize(mySession Session)

{

if (Session == null) return null;

Stream stream = null;

Byte[] state = null;

try

{

IFormatter formatter = new BinaryFormatter();

stream = new MemoryStream();

formatter.Serialize(stream, Session);

state = new Byte[stream.Length];

stream.Position = 0;

stream.Read(state, 0, (int)stream.Length);

stream.Close();

}

finally

{

if (stream != null)

stream.Close();

}

return state;

}

SessionPage类以及与它相关的类被封装在SessionUtility组件中。在一个新ASP.NET项目中,需要作SessionUtility组件的引用,为了与传统的ASP代码共享对话,每个页面由SessionPage代替Page类衍生出来。一旦移植完成了,新应用程序能通过说明SessionPage类中定义的对话变量切换回使用原来的HttpSession对象来显示基本的HttpSession。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有