segunda-feira, 31 de agosto de 2009

Session Transfer

Bom Galera,
Um tempo atrás tive de desenvolver uma aplicação híbrida, que integrava o velho ASP com .NET2.0, porém como todos sabem, estas tecnologias não compartilham as sessions, e então? como fazer o .net ler as sessions do asp?
Pra resolver isto tive de apelar para uma metodologia que usa banco de dados, vou explicar tudo, passo-a-passo logo, mas antes irei apresentar algumas características deste projeto para que vocês entendam as limitações que a solução deveria respeitar.1º. O projeto se trata de um sistema modular feito em ASP.
2º. Os módulos novos deveriam, mandatoriamente, sem feitos em .net VB 2.0
3º. O banco deve seguir a arquitetura posta no projeto inicial, que é MS-SQL 2000
Depois destas noticias desanimadoras, vamo à solução.
Devo criar uma tabela no banco de dados com a seguinte modelagem:
O Script para a criação da tabela é:
CREATE TABLE [dbo].[SessionTransfer] (
[IdSecao] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Chave] [varchar] (100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
[Valor] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
[Data] [datetime] NOT NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
ALTER TABLE [dbo].[SessionTransfer] ADD 
CONSTRAINT [DF_SessionTransfer_Data] DEFAULT (getdate()) FOR [Data]
GO


Vamos para os codigos em ASP e .NET:
Após o sistema principal em ASP fazer a criação das sessions que o projeto precisa, tais como permissões de acesso, regras de hierarquia, etc, eu chamo o arquivo "sessiontransfer.asp".
ATENÇÃO:
O código demonstrados neste post são apenas didáticos e não devem ser utilizados da forma como são apresentados, pois possuem diversas falhas de segurança como SQL-Injection por exemplo. Caso você queira utilizá-lo, apenas baseie sua lógica neste exemplo, mas construa um código seguindo as condutas de boas práticas.

< ! - - #include file="../_include/_abreconexao.asp"  - -  >
< %
For i = 1 to (Session.Contents.Count -1)
strSql = "INSERT INTO SessionTransfer (IdSecao, Chave, Valor) VALUES ('" &
strSql = strSql & Session.SessionID & "', '" & Session.Contents.Key(i) & "', '" & Session.Contents.Item(i) & "')"
DBCon.Execute (strSql)
Next
Response.Redirect("SessionTransfer.aspx?IdSecao=" & Session.SessionID)
% >

Como vocês percebem, este código varre todas as chaves de sessions da aplicação e as envia para o banco. Após este processo ele redireciona para o arquivo em .NET "SessionTransfer.aspx", com a devida parametrização de identificação da Session.
Segue o código do "SessionTransfer.aspx":
Imports System
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Collections
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls

Partial Public Class SessionTransfer
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim objConn As SqlConnection = New SqlConnection(SqlHelper.m_strConn)
Dim objCmd As SqlCommand = New SqlCommand()
Dim objAdap As SqlDataAdapter = New SqlDataAdapter()
Dim objDataSet As DataSet = New DataSet()
Dim strIdSecao As String = Request.QueryString("IdSecao").ToString()
Dim i As Integer = 0
objConn.Open()
objCmd.CommandTimeout = 300
objCmd.CommandType = CommandType.Text
objCmd.Connection = objConn
objCmd.CommandText = "SELECT Chave, Valor FROM SessionTransfer WHERE IdSecao = '" + strIdSecao + "'"
objAdap.SelectCommand = objCmd
objAdap.Fill(objDataSet)
For i = 0 To objDataSet.Tables(0).Rows.Count - 1
If (Session(objDataSet.Tables(0).Rows(i)("Chave").ToString()) <> Nothing) Then
Session.Remove(objDataSet.Tables(0).Rows(i)("Chave").ToString())
End If
Session.Add(objDataSet.Tables(0).Rows(i)("Chave").ToString(), objDataSet.Tables(0).Rows(i)("Valor").ToString())
Response.Write(objDataSet.Tables(0).Rows(i)("Chave").ToString())
Response.Write(objDataSet.Tables(0).Rows(i)("Valor").ToString())
Next
        objCmd.CommandText = "DELETE FROM SessionTransfer WHERE IdSecao = " + strIdSecao
        objCmd.ExecuteNonQuery()
        objCmd.CommandText = "DELETE FROM SessionTransfer WHERE DATEDIFF(hh, Data, GETDATE()) >= 1"
        objCmd.ExecuteNonQuery()
End Sub
End Class

Neste arquivo eu recupero os valores baseado na SessionID passada por parâmetro, crio as Sessions para o .NET e após eu deleto do banco todas as chaves da session que busquei.
Notem que também faço uma segunda exclusão procurando por sessions cadastradas com mais de 1 dia.

Para exemplo isso serve, mas lembrem-se de que isso é só um exemplo!!! muito cuidado ao usarem querys SQL que são concatenadas com parâmetros query-string! Ainda mais sem tratamento como o do exemplo.
Na realidade, meu conselho é: Nunca façam isso! =D Mas para didática isso já ajuda banstante.

abraços!

Nenhum comentário:

Postar um comentário