CategoriesUncategorized

Shared Session Management for Classic ASP and .NET Core Integration

Organizations often face challenge of maintaining legacy Classic ASP applications while developing new features in .NET Core. Complete system migration is not always practical solution due to complexity, risk, and cost. In this article, we are going to explore how to implement distributed session management that allows both systems to work together effectively.

Understanding the Architecture

In typical scenario, legacy Classic ASP application serves as main website (e.g., www.company.com), while new .NET Core application runs on subdomain (e.g., app.company.com). Main challenge is maintaining user session across these separate applications. Solution is to implement centralized session management using shared database.

Database Design

Here is simple but effective database structure:

CREATE TABLE [dbo].[DistributedSessions]
(
    [SessionId] VARCHAR(50) PRIMARY KEY,
    [Username] NVARCHAR(100) NOT NULL,
    [UserData] NVARCHAR(MAX),
    [LastAccessed] DATETIME NOT NULL,
    [CreatedOn] DATETIME NOT NULL,
    [ExpiresOn] DATETIME NOT NULL
)

CREATE INDEX IX_Sessions_Username ON [dbo].[DistributedSessions] ([Username])
CREATE INDEX IX_Sessions_Expiration ON [dbo].[DistributedSessions] ([ExpiresOn])

Classic ASP Implementation

Here is helper class for Classic ASP (saved as session.asp):

<%
Class DistributedSession
    Private connString
    Private sessionId

    Private Sub Class_Initialize()
        connString = "your_connection_string_here"
        sessionId = Request.Cookies("DistSessionId")

        If sessionId = "" Then
            sessionId = CreateNewSession()
        End If
    End Sub

    Private Function CreateNewSession()
        ' Generate unique session ID
        Dim newId
        newId = Replace(CreateObject("Scriptlet.TypeLib").GUID, "-", "")

        ' Create cookie
        Response.Cookies("DistSessionId") = newId
        Response.Cookies("DistSessionId").Domain = ".company.com"

        CreateNewSession = newId
    End Function

    Public Function GetUserData()
        Dim conn, rs
        Set conn = CreateObject("ADODB.Connection")
        conn.Open connString

        Set rs = conn.Execute("SELECT UserData FROM DistributedSessions " & _
                            "WHERE SessionId = '" & sessionId & "' " & _
                            "AND ExpiresOn > GETDATE()")

        If Not rs.EOF Then
            GetUserData = rs("UserData")
        End If

        rs.Close
        conn.Close
    End Function

    Public Sub SetUserData(userData)
        Dim conn
        Set conn = CreateObject("ADODB.Connection")
        conn.Open connString

        conn.Execute "UPDATE DistributedSessions " & _
                    "SET UserData = '" & Replace(userData, "'", "''") & "', " & _
                    "LastAccessed = GETDATE() " & _
                    "WHERE SessionId = '" & sessionId & "'"

        conn.Close
    End Sub
End Class
%>

.NET Core Implementation

Create SessionService class in your .NET Core project:

public class DistributedSessionService
{
    private readonly string _connectionString;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public DistributedSessionService(
        IConfiguration configuration,
        IHttpContextAccessor httpContextAccessor)
    {
        _connectionString = configuration.GetConnectionString("SessionDb");
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<UserSessionData> GetUserDataAsync()
    {
        var sessionId = _httpContextAccessor.HttpContext.Request
            .Cookies["DistSessionId"];

        if (string.IsNullOrEmpty(sessionId))
            return null;

        using var connection = new SqlConnection(_connectionString);
        await connection.OpenAsync();

        var userData = await connection.QueryFirstOrDefaultAsync<string>(
            @"SELECT UserData 
              FROM DistributedSessions 
              WHERE SessionId = @SessionId 
              AND ExpiresOn > GETDATE()",
            new { SessionId = sessionId });

        return userData != null 
            ? JsonSerializer.Deserialize<UserSessionData>(userData)
            : null;
    }

    public async Task SetUserDataAsync(UserSessionData userData)
    {
        var sessionId = _httpContextAccessor.HttpContext.Request
            .Cookies["DistSessionId"];

        using var connection = new SqlConnection(_connectionString);
        await connection.OpenAsync();

        await connection.ExecuteAsync(
            @"UPDATE DistributedSessions 
              SET UserData = @UserData,
                  LastAccessed = GETDATE()
              WHERE SessionId = @SessionId",
            new { 
                SessionId = sessionId,
                UserData = JsonSerializer.Serialize(userData)
            });
    }
}

Implementation Benefits

This approach provides several important advantages:

  1. Cost Effective
    • Allows continued use of stable legacy system
    • Minimizes risk of full migration
    • Reduces immediate development costs
  2. Technical Benefits
    • Shared authentication state
    • Consistent user experience
    • Scalable solution
  3. Business Benefits
    • Gradual migration path
    • Maintain business operations
    • Lower training costs

Important Considerations

When implementing this solution, remember these points:

  1. Security
    • Use parameterized queries to prevent SQL injection
    • Implement proper session timeout
    • Encrypt sensitive session data
    • Use secure cookie settings
  2. Performance
    • Implement caching where appropriate
    • Create maintenance job to clean expired sessions
    • Monitor database growth
  3. Maintenance
    • Log session operations for troubleshooting
    • Monitor session timeouts
    • Regular cleanup of expired sessions

    Conclusion

    Distributed session management provides practical solution for organizations that need to maintain legacy Classic ASP applications while developing new features in .NET Core. This approach reduces migration risks and costs while providing consistent user experience.

    Implementation requires careful planning and consideration of security implications, but benefits often outweigh complexity of setup. Organizations can continue using valuable legacy systems while gradually transitioning to modern technology stack.

    Leave a Reply

    Your email address will not be published. Required fields are marked *