动网论坛,站长建站首选,国内使用量最多的论坛软件 动网论坛官方技术讨论区 站长工具 申请属于您自己的免费论坛
首页 | 新闻资讯 | 网站运营 | 网络编程 | 数据库 | 服务器 | 网页设计 | 图像媒体 | 网络应用 | 搜索优化 | 资源下载 | 动网主机 | DVBOX
    本站内  互联网 ASP论坛  ASP.Net论坛  PHP论坛
   Asp → 阅读文章

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

作者:佚名 来源:开发者俱乐部 
阅读 3811 人次 , 2003-8-15 8:58:00 

[前言:]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.数据流简单图 [img]upload/03081508577587.gif[/img]   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。  
 本文TagsC#  
 收藏本文  打印本文  论坛讨论  关闭窗口
· 上一篇:在ASP与ASP.NET之间共享对话状态(2)
· 下一篇:17种正则表达式
· JScript 方法 - getUTCSeconds 方法
· NextRecordset 和 GetRows 双簧合奏
· 披著羊皮的大野狼 - Session
· ASP实用大全-ASP对象(6)
· IP地址分段计算


关于本站 | 联系我们 | 业务合作 | 客户案例 | 诚聘英才 | 广告合作 | 收藏本站
海口动网先锋网络科技有限公司版权所有
Copyright © 2000 - 2006 Cndw.Com
中华人民共和国电信与信息服务业务经营许可证编号 琼 ICP 020077