zoukankan      html  css  js  c++  java
  • ASP和ASP.NET之间是否可以共享Session

    ASP.NET Technical Articles
    How to Share Session State Between Classic ASP and ASP.NET
     

    Billy Yuen
    Microsoft Corporation

    February 2003

    Applies to:
       Microsoft® ASP.NET

    Summary: Discusses how to share session state between classic ASP and Microsoft ASP.NET using Microsoft .NET Framework classes and the serialization feature of the .NET Framework. Sharing session state allows converting existing ASP applications to ASP.NET applications in stages while running the applications side by side. (12 printed pages)

    Download the source code for this article.


    Contents

    Introduction
    Conceptual Overview
    ASP.NET Implementation
    ASP Implementation
    Demo Program
    Incorporating the COM Object in an Existing ASP Application
    Limitation/Improvement
    Conclusion

    Introduction

    Microsoft® ASP.NET is the latest Microsoft technology for developing Web-based applications. It offers a number of advantages over the classic ASP script technology, including: 1) a better development structure by separating the UI presentation from business logic; 2) its code is fully compiled instead of interpreted as in classic ASP; and 3) its compile feature in conjunction with its caching support means significantly better performance for sites written in ASP.NET over equivalent sites written in classic ASP.

    Despite the potential benefit of converting existing ASP applications to ASP.NET, many existing ASP applications are mission critical and complex. The conversion process could be resource intensive and induce additional risk to the existing application. One approach to address these issues is to run the ASP and ASP.NET side by side, and convert one section of the application at a time to ASP.NET. In order to run the new and old application side by side, a mechanism is needed to share the session state between classic ASP and ASP.NET. In this article, I'll discuss how the session state can be shared by using several classes and the serialization feature of the Microsoft® .NET Framework.

    Conceptual Overview

    Cookies are the most common way for Web applications to identify the user session, and can be used to identify session state for both classic ASP and ASP.NET. Session state information is stored in memory in ASP script and can't be shared with other applications, such as ASP.NET. If the session state is stored in a common format in Microsoft® SQL Server, the session state can be accessible by both classic ASP and ASP.NET.

    In this example, a cookie named mySession is used to identify the user session. When a user makes a request to the Web application, the user will be issued a unique cookie to identify the session. On subsequent request, the browser will send the unique cookie back to the server to identify the session. Before the requested Web page is loaded, a custom object will reload the user session data from SQL Server using the unique cookie. The session state is accessible in the Web page through the custom object. After the Web request is finished, the session data will be persisted back to the SQL Server as the request terminates (see Figure 1).

    Figure 1. Sample data flow

    ASP.NET implementation

    In ASP.NET, every Web page derives from the System.Web.UI.Page class. The Page class aggregates an instance of the HttpSession object for session data. In this example, a custom Page class called SessionPage is derived from the System.Web.UI.Page to offer all the same features as the Page class. The only difference with the derived page is that the default HttpSession is overridden with a custom session object. (Using the new modifier for the instance variable, C# allows the derived class to hide members of the base class.)

       public class SessionPage : System.Web.UI.Page
    {
    ...
    public new mySession Session = null;
    ...
    }
    

    The custom session class is responsible for storing the session state in memory using the HybridDictionary object. (HybridDictionary can efficiently handle any number of session elements.) The custom session class will limit the session data type to be string only for interoperability with the classic ASP. (The default HttpSession allows any type of data to be stored in the session, which will not interoperate with the classic 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;
    }
    }
    }
    

    The Page class exposes different events and methods for customization. In particular, the OnInit method is used to set the initialize state of the Page object. If the request does not have the mySession cookie, a new mySession cookie will be issued to the requester. Otherwise, the session data will be retrieved from SQL Server using a custom data access object, SessionPersistence. The dsn and SessionExpiration values are retrieved from the 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);
    }
    

    The SessionPersistence class uses the BinaryFormatter of the Microsoft .NET Framework to serialize and deserialize the session state in binary format for optimal performance. The resulting binary session state data can then be stored in the SQL Server as an image field type.

          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;
    }
    

    At the end of the request, the Page class Unload event is fired, and an event handler registered with the Unload event will serialize the session data into binary format and save the resulting binary data into 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;
    }
    

    The SessionPage class and its associated classes are packaged in the SessionUtility assembly. In a new ASP.NET project, a reference will be made to the SessionUtility assembly, and every page will derive from the SessionPage instead of from the Page class in order to share session with classic ASP codes. Once the porting is completed, the new application can switch back to use the native HttpSession object by commenting out the Session variable declaration in the SessionPage class to unhide the base HttpSession.

    ASP Implementation

    The native ASP session can only store session data in memory. In order to store the session data to SQL Server, a custom Microsoft® Visual Basic® 6.0 COM object is written to manage the session state instead of using the native session object. This COM object will be instantiated in the beginning of each Web request and reload the session data from SQL Server. When the ASP script is finished, this object will be terminated and the session state will be persisted back to SQL Server.

    The primary purpose of the Visual Basic 6 COM Session object is to provide access to the Microsoft® Internet Information Server intrinsic objects. The Visual Basic 6.0 COM Session object uses the mySession class of SessionUtility assembly to hold the session state, and the SessionPersistence class of SessionUtility to load and save session data with SQL Server. The mySession and SessionPersistence classes are exposed as COM objects using the regasm.exe utility. The regasm.exe utility can register and create a type library for the COM client to consume Framework classes.

    The session state information is reloaded during the construction of the object. The constructor (class_initialize) will first retrieve the session cookie, session timeout (SessionTimeOut), and database connection string (SessionDSN) from the Application object, and create an instance of the class mySession to hold the session data. Then the constructor will try to reload the session data from SQL Server with the given cookie. If the SQL Server does not have the session information, or the session has been expired, a new cookie will be issued. If the SQL Sever does return with the session state data, the session state will be stored in the mySession object.

    Private Sub Class_Initialize()
    On Error GoTo ErrHandler:
    Const METHOD_NAME As String = "Class_Initialize"
    Set mySessionPersistence = New SessionPersistence
    Set myObjectContext = GetObjectContext()
    mySessionID = ReadSessionID()
    myDSNString = GetConnectionDSN()
    myTimeOut = GetSessionTimeOut()
    myIsNewSession = False
    Call InitContents
    Exit Sub
    ErrHandler:
    Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
    End Sub
    Private Sub InitContents()
    On Error GoTo ErrHandler:
    Const METHOD_NAME As String = "InitContents"
    If mySessionID = "" Then
    Set myContentsEntity = New mySession
    mySessionID = mySessionPersistence.GenerateKey
    myIsNewSession = True
    Else
    Set myContentsEntity =
    mySessionPersistence.LoadSession(mySessionID, myDSNString, myTimeOut)
    End If
    Exit Sub
    ErrHandler:
    Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
    End Sub
    

    When the object instance goes out of scope in the script, the destructor (class_terminate) will execute. The destructor will persist the session data using the SessionPersistence.SaveSession() method. If this is a new session, the destructor will also send the new cookie back to the browser.

    Private Sub Class_Terminate()
    On Error GoTo ErrHandler:
    Const METHOD_NAME As String = "Class_Terminate"
    Call SetDataForSessionID
    Exit Sub
    ErrHandler:
    Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
    End Sub
    Private Sub SetDataForSessionID()
    On Error GoTo ErrHandler:
    Const METHOD_NAME As String = "SetDataForSessionID"
    Call mySessionPersistence.SaveSession(mySessionID,
    myDSNString, myContentsEntity, myIsNewSession)
    If myIsNewSession Then Call WriteSessionID(mySessionID)
    Set myContentsEntity = Nothing
    Set myObjectContext = Nothing
    Set mySessionPersistence = Nothing
    Exit Sub
    ErrHandler:
    Err.Raise Err.Number, METHOD_NAME & ":" & Err.Source, Err.Description
    End Sub

    You can download the source code of ASP.NET SessionUtility project, the COM Session Manager, and the Demo code by clicking the link at the top of the article.

  • 相关阅读:
    trim标签:可以自定义字符串的截取规则
    登录框(用获取value值方法)
    C++在ARM Linux下的交叉编译
    happybase导入报错:thriftpy.parser.exc.ThriftParserError: ThriftPy does not support generating module with path in protocol 'c'
    Nginx报错总结
    ubuntu安装Nginx
    mqtt在debian strench 9 docker环境下的搭建
    evokly/kafka-connect-mqtt 不支持kafka集群部署
    树莓派mqtt安装
    kafka和mqtt的区别和联系
  • 原文地址:https://www.cnblogs.com/RuiLei/p/662024.html
Copyright © 2011-2022 走看看