Wspoldzielenie stanu sesji pomiedzy klasycznymi aplikacjami ASP a aplikacjami ASP NET sfor


Współdzielenie stanu sesji pomiędzy klasycznymi aplikacjami ASPaplikacjami ASP.NET

Billy Yuen
Microsoft Corporation

Dotyczy:
Microsoft® ASP.NET

Streszczenie

W artykule wyjaśniono,jaki sposób współdzielić stan sesji pomiędzy klasycznym ASPASP.NET, wykorzystując klasy Microsoft .NET Framework oraz funkcjonalność serializacji platformy .NET Framework. Współdzielenie stanu sesji pozwala na przeprowadzenie konwersji istniejących aplikacji ASP do ASP.NET etapami, gdy staranowa część aplikacji działają równolegle.
Długość dokumentu —
12 stron po wydrukowaniu

Pobierz przykładowy kod źródłowy do tego artykułu

Spis treści

Wstęp
Wstęp teoretyczny
ImplementacjaASP.NET
ImplementacjaASP
Program demonstracyjny
Włączanie obiektów COMistniejącą aplikację ASP
Ograniczeniamożliwości rozwoju kodu
Podsumowanie

Wstęp

ASP.NET firmy Microsoft® jest najnowszą technologią do tworzenia aplikacji internetowych. Zalety ASP.NETporównaniuklasycznym ASP to: 1) lepsza struktura wdrożeniowa dzięki oddzieleniu warstwy prezentacyjnej (interfejs użytkownika) od logiki biznesowej; 2) kod ASP.NET jestpełni kompilowanyprzeciwieństwie do kodu klasycznego ASP, który jest interpretowany; 3) możliwość kompilowania kodupołączeniubuforowaniem oznacza znacznie większą wydajność witryn napisanychASP.NETporównaniuich odpowiednikami utworzonymiklasycznym ASP.

Konwersja aplikacji ASP do ASP.NET może przynieść wiele korzyści, jednak istnieje sporo aplikacji ASPznaczeniu krytycznym. Aplikacje takie często są bardzo skomplikowane. Proces konwersji może wymagać zaangażowania dużych zasobówmoże powodować niepoprawne działanie istniejącej aplikacji. Jednym ze sposobów na rozwiązanie tych problemów jest równoległe uruchamianie aplikacji ASPASP.NET oraz konwersja aplikacji moduł po module. Aby równolegle uruchomić starąnową aplikację, wymagane jest współdzielenie stanu sesji pomiędzy klasycznym ASPASP.NET.niniejszym artykule wyjaśniono, jakużyciem kilku klas oraz funkcji serializacji Microsoft® .NET Framework współdzielić stan sesji pomiędzy aplikacjami.

Wstęp teoretyczny

Pliki cookie to najpopularniejszy sposób identyfikacji sesji użytkownikaaplikacjach internetowych, który może służyć do identyfikacji stanu sesji zarównoASP jak i w ASP.NET. Informacjastanie sesji jest przechowywanapamięci skryptu ASPnie może być współdzielonainnymi aplikacjami, takimi jak ASP.NET. Jeśli natomiast stan sesji byłby przechowywanystandardowym formaciebazie Microsoft® SQL Server, wówczas dostęp do niego mógłby być realizowany zarówno przez klasyczny kod ASPjakkod ASP.NET.

niniejszym przykładzie do identyfikacji sesji użytkownika używany jest plik cookienazwie mySession. Gdy użytkownik wysyła żądanie do aplikacji internetowej, serwer tworzy unikatowy plik cookie identyfikujący sesjęwysyła go do użytkownika. Przy kolejnym żądaniu unikatowy plik cookie wysyłany jestpowrotem do serwera. Plik cookie umożliwia identyfikację sesji użytkownikazaładowanieserwera SQL (za pomocą specjalnie przygotowanej klasy) danychsesji użytkownika. Ta specjalnie przygotowana klasa zapewnia dostęp do całego stanu sesji w aplikacji internetowej. Po zakończeniu obsługi żądania, danesesji zostaną ponownie zapisanebazie serwera SQL (patrz ilustracja 1).

0x01 graphic

Ilustracja 1. Przepływ danych

ImplementacjaASP.NET

Każda strona internetowa ASP.NET jest klasą pochodną klasy System.Web.UI.Page. Klasa Page zawiera instancję obiektu HttpSession,którym przechowywane są dane sesji.tym przykładzie opracowano niestandardową klasę pochodną System.Web.UI.Page — klasęnazwie SessionPage, zapewniającą taką samą funkcjonalność co klasa Page. Jedyną różnicą pomiędzy klasami SessionPage oraz Page jest to, że domyślny obiekt HttpSession został zastąpiony niestandardowym obiektem sesji (w języku C# zastosowanie modyfikatora new do składowej klasy pozwala ukryć składową odziedziczoną po klasie podstawowej).

public class SessionPage : System.Web.UI.Page

{

...

public new mySession Session = null;

...

}

Niestandardowa klasa sesji do przechowywania stanu sesjipamięci operacyjnej wykorzystuje obiekt HybridDictionary (obiekt HybridDictionary może sprawnie przechowywać nieograniczoną liczbę elementów sesji). Aby umożliwić współpracęklasycznym ASP, typ danych przechowywanych wewnątrz stanu sesji został ograniczony do typu string (domyślny obiekt HttpSession dopuszcza przechowywanie danych dowolnego typu, nie jest to jednak zgodneklasycznym 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;

}

}

}

Klasa Page umożliwia dostosowywanie działania różnych zdarzeńmetod. Metoda OnInit jest używana do inicjowania stanu obiektu Page. Jeżeliżądaniu nie przesłano pliku cookie mySession, do przeglądarki, która przesłała żądanie, zostanie wysłany nowy plik cookie mySession. Jeśli plik cookie został przesłanyżądaniu, to jego zawartość wykorzystana jest do pobrania stanu sesjiserwera SQL. Służy do tego niestandardowy obiekt dostępu do danychnazwie SessionPersistence. Nazwa źródła danych DSN oraz wartość SessionExpiration pobierane pliku 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);

}

Klasa SessionPersistence do serializacjideserializacji stanu sesjiformacie binarnym używa obiektu BinaryFormatterMicrosoft .NET Framework, co umożliwia uzyskanie optymalnej wydajności. Otrzymane dane binarne mogą być składowanebazie danych serwera SQL jako pole typu image.

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;

}

Na koniec obsługi żądania zgłaszane jest zdarzenie Unload klasy Page. Procedura obsługi, zarejestrowana dla zdarzenia Unload, serializuje dane sesji do formatu binarnegozachowuje binarne dane wynikowebazie danych serwera SQL.

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;

}

Klasa SessionPageinne związanenią klasy znajdują siępodzespole SessionUtility. Aby móc współdzielić stan sesjiaplikacjami napisanymiklasycznym ASP,nowym projekcie ASP.NET należy utworzyć referencję do podzespołu SessionUtility,każda strona internetowa musi być klasą pochodną klasy SessionPage,nie klasy Page. Po zakończeniu konwersji kodu, nowa aplikacja może zostać zmodyfikowana tak, by używała rodzimego obiektu HttpSession. Wystarczy usunąć deklarację składowej Sessionklasy SessionPageodsłonić tym samym obiekt HttpSession.

ImplementacjaASP

Standardowy obiekt sesji, dostępnyASP, może przechowywać dane jedyniepamięci operacyjnej. Aby składować danebazie danych na serwerze SQL, konieczne jest napisanie — na przykładMicrosoft® Visual Basic® 6.0 — własnego obiektu COM, który zastąpi obiekt sesji wbudowanyASP. Na początku obsługi każdego żądania tworzona będzie instancja tego obiektu. Kod inicjujący obiektu załaduje następnie dane sesjiserwera SQL. Po wykonaniu skryptu ASP instancja obiektu zostanie zwolniona,dane sesji trafiąpowrotem do serwera SQL.

Podstawowym zadaniem obiektu sesji jest zapewnienie dostępu do wewnętrznych obiektów usług IIS. Obiekt sesji do przechowywania stanu sesji używa klasy mySessionpodzespołu SessionUtility, natomiast do ładowaniazapisywania danych sesjibazie danych serwera SQL klasy SessionPersistence tego podzespołu. Klasy mySession oraz SessionPersistence muszą zostać udostępnione jako obiekty COM za pomocą narzędzia regasm.exe. Regasm.exe pozwala na utworzeniezarejestrowanie biblioteki typów, co umożliwia wykorzystywanie klas .NET Framework przez klientów COM.

Informacjastanie sesji ładowana jest podczas tworzenia obiektu. Konstruktor obiektu (class_initialize) najpierw pobieraobiektu Application plik cookie sesji, czas trwania sesji (SessionTimeOut) oraz łańcuch połączeniabazą danych (SessionDSN). Następnie tworzy instancję obiektu mySession, który będzie przechowywał dane sesji. Po wykonaniu powyższych czynności konstruktor próbuje załadować stan sesjiserwera SQL, odpowiadający otrzymanemu plikowi cookie. Jeśli serwer SQL nie posiada informacjisesji lub jeśli sesja wygasła, zostanie utworzony nowy plik cookie. Jeśli serwer SQL zwróci dane sesji, zostaną one umieszczoneobiekcie mySession.

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

Po zakończeniu wykonywania skryptu ASP uruchamiany jest destruktor (class_terminate) obiektu przechowującego bieżące dane sesji. Destruktor zapisze dane sesji przy użyciu metody SessionPersistence.SaveSession(). Jeśli jest to nowa sesja, destruktor wyśle do przeglądarki nowy plik cookie.

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

Kod źródłowy projektu SessionUtility dla ASP.NET, menedżer sesji COM oraz kod programu demonstracyjnego można pobrać klikając odnośnik znajdujący się na początku niniejszego artykułu.

Program demonstracyjny

Program demonstracyjny inkrementuje zmienną liczbowąwyświetla wynik wykonanej operacji. Liczba będzie wzrastać niezależnie od tego, czy ładowana będzie strona ASP czy ASP.NET, ponieważ wartość liczbowa przechowywana jestbazie danych serwera SQLjest współdzielona pomiędzy klasycznym ASPASP.NET.

Instalacja programu demonstracyjnego:

  1. Utwórz nową bazę danych o nazwie SessionDemoDb.

  2. Utwórz tabelę SessState (osql.exe -E -d SessionDemoDb -i Session.sql).

  3. Utwórz na serwerze IIS nowy katalog wirtualny o nazwie Demo.

  4. Wyłącz obsługę sesji ASP (na karcie konfiguracji aplikacji).

  5. Do utworzonego wcześniej katalogu wirtualnego skopiuj pliki web.config, testPage.aspx, Global.asa, testPage.asp oraz GlobalInclude.asp.

  6. Zmodyfikuj nazwę DSN w plikach Global.asa oraz web.config. Ustawienie automatycznego czasu zakończenia sesji jest opcjonalne. Wartość domyślna to 20 minut.

  7. Plik SessionUtility.dll umieść w Global Assembly Cache (gacutil /i SessionUtility.dll).

  8. Używając polecenia regasm.exe udostępnij plik SessionUtility.dll jako obiekt COM (regasm.exe SessionUtility.dll /tlb:SessionUtility.tlb).

  9. Skopiuj plik SessionManager.dll do folderu lokalnego i zarejestruj go używając polecenia regsvr32.exe (regsvr32 SessionManager.dll).

  10. Przypisz prawa odczytu i wykonania pliku SessionMgr.dll dla konta IUSR_<nazwa_komputera>.

Uruchomienie programu demonstracyjnego:

  1. Uruchom przeglądarkę Microsoft® Internet Explorer.

  2. Załaduj stronę testPage.asp wykorzystującą klasyczne ASP. W przeglądarce powinna pojawić się liczba „1”.

  3. Kliknij przycisk Odśwież, aby ponownie załadować stronę. Liczba widoczna na ekranie powinna się zwiększyć.

  4. Załaduj stronę testPage.aspx wykorzystującą ASP.NET. Liczba powinna ponownie wzrosnąć.

  5. Proces ten powinien poprawnie przebiegać również w przypadku rozpoczęcia testu od załadowania strony testPage.aspx.

Włączanie obiektów COMistniejącą aplikację ASP

Powszechną praktyką, stosowaną przy tworzeniu aplikacji ASP, jest dołączanie (include) na początku każdego skryptu pliku zawierającego współdzielone fragmenty kodustałe. Najlepszym sposobem na włączenie własnego obiektu sesji jest umieszczenie kodu tworzącego instancję tego obiektu we wspólnym pliku dołączanym (include file). Ostatni krok to po prostu zastąpienie wszystkich referencji do obiektu Session referencjami do naszego własnego obiektu przechowującego stan sesji.

Ograniczeniamożliwości rozwoju kodu

Podanego tu rozwiązania nie można zastosowaćistniejących aplikacjach ASP, które obiekt Session wykorzystują do przechowywania obiektów COM.takim wypadku do poprawnego działania niestandardowego obiektu sesji potrzebny jest własny mechanizm serializowaniadeserializowania stanu sesji. Przedstawione tu rozwiązanie nie obsługuje także przechowywania tablic łańcuchów znaków. Realizacja tej funkcjonalności nie wymaga dużego nakładu pracy — do łączenia wszystkich elementów tablicyjeden ciąg można wykorzystać funkcję Join języka Microsoft® Visual Basic® 6.0,do podzielenia ciągupowrotem na poszczególne elementy tablicy funkcję Split..NET Framework metody Join oraz Split są elementami klasy String.

Podsumowanie

ASP.NET to nowe podejście do programowaniazupełnie nowa architektura aplikacji. Technologia ta ma wiele zaletstosunku do klasycznego ASP. Chociaż przejścieASP do ASP.NET nie jest procesem prostym, lepszy model programowaniapoprawiona wydajność wynagradza czas poświęcony na konwersję kodu. Mimo że opisane tutaj rozwiązanie nie umożliwia składowania obiektów COMobiekcie Session, powinno znacznie uprościć proces migracji.

autorze

Billy Yuen jest pracownikiem Microsoft Technology CenterDolinie Krzemowejpółnocnej Kalifornii. Ośrodek ten koncentruje się na tworzeniu rozwiązań opartych na Microsoft .NET Framework.autorem można skontaktować się pod adresem billyy@microsoft.com.

10



Wyszukiwarka

Podobne podstrony:
BizAgi Studio Cz, 5 Stworzeni aplikacji zewn trznej w ASP NET
Podstawy ASP NET 2 0 – tworzenie stron WWW oraz aplikacji Web
BizAgi Studio Część 5 Stworzeni aplikacji zewnętrznej w ASP NET
BizAgi Studio Cz, 5 Stworzeni aplikacji zewn trznej w ASP NET
ASP NET Web Forms Kompletny przewodnik dla programistow interaktywnych aplikacji internetowych w Vis
ASP NET MVC 4 Programowanie aplikacji webowych aspm4w
ASP NET Web Forms Kompletny przewodnik dla programistow interaktywnych aplikacji internetowych w Vis
ASP NET MVC 4 Programowanie aplikacji webowych
ASP NET Web Forms Kompletny przewodnik dla programistow interaktywnych aplikacji internetowych w Vis
Aplikacje Web w ASP NET 2 0
ASP NET MVC 4 Programowanie aplikacji webowych
ASP NET MVC 4 Programowanie aplikacji webowych 2
ASP NET Web Forms Kompletny przewodnik dla programistow interaktywnych aplikacji internetowych w Vis
ASP NET MVC 4 Programowanie aplikacji webowych aspm4w
C Tworzenie aplikacji graficznych w NET 3 0 cshne3
C Tworzenie aplikacji graficznych w NET 30
C Tworzenie aplikacji graficznych w NET 30

więcej podobnych podstron