aspnetcore/migration/fx-to-core/areas/session.md
Session state is a critical component of many web applications, storing user-specific data across HTTP requests. When migrating from ASP.NET Framework to ASP.NET Core, session state presents unique challenges because the two frameworks handle sessions very differently.
ASP.NET Framework and ASP.NET Core have fundamentally different approaches to session management:
These differences mean you can't simply move your session code from Framework to Core without changes.
You have three main approaches for handling session state during migration:
For most applications, migrating to ASP.NET Core session provides the best performance and maintainability. However, larger applications or those with complex session requirements may benefit from an incremental approach using the System.Web adapters.
You have three main options for migrating session state from ASP.NET Framework to ASP.NET Core. Your choice depends on your migration timeline, whether you need to run both applications simultaneously, and how much code you're willing to rewrite.
Answer these questions to choose your approach:
Are you doing a complete rewrite or incremental migration?
Do both your ASP.NET Framework and ASP.NET Core apps need to access the same session data?
Before diving into implementation details, it's important to understand how ASP.NET Framework and ASP.NET Core handle session state differently:
byte[]| Approach | Code Changes | Performance | Session Sharing | When to Use |
|---|---|---|---|---|
| Built-in ASP.NET Core | High - Rewrite all session code | Best | None | Complete rewrites, performance-critical apps |
| Wrapped ASP.NET Core | Low - Keep existing session patterns | Good | None | Incremental migrations, no shared state needed |
| Remote app | Low - Keep existing session patterns | Fair | Full | Running both apps simultaneously |
The System.Web adapters enable the "Wrapped" and "Remote app" approaches by bridging the differences between ASP.NET Framework and Core session implementations through two key interfaces:
Microsoft.AspNetCore.SystemWebAdapters.ISessionManager: Accepts an xref:Microsoft.AspNetCore.Http.HttpContext and session metadata, returns an ISessionState objectMicrosoft.AspNetCore.SystemWebAdapters.ISessionState: Describes session object state and backs the xref:System.Web.SessionState.HttpSessionState typeChoose this approach when you're performing a complete migration and can rewrite session-related code to use ASP.NET Core's native session implementation.
ASP.NET Core provides a lightweight, high-performance session state implementation that stores data as byte[] and requires explicit serialization. This approach offers the best performance but requires more code changes during migration.
For details on how to set this up and use it, see the [ASP.NET session documentation]((xref:fundamentals/app-state.md).
| Pros | Cons |
|---|---|
| Best performance and lowest memory footprint | Requires rewriting all session access code |
| Native ASP.NET Core implementation | No automatic object serialization |
| Full control over serialization strategy | No session locking (concurrent requests may conflict) |
| No additional dependencies | Breaking change from ASP.NET Framework patterns |
| Supports all ASP.NET Core session providers | Session keys are case-sensitive (unlike Framework) |
When migrating to built-in ASP.NET Core session:
Code changes required:
Session["key"] with HttpContext.Session.GetString("key")Session["key"] = value with HttpContext.Session.SetString("key", value)Data migration:
Testing strategy:
When to choose this approach:
The xref:System.Web.SessionState.HttpSessionState object requires serialization for remote app session state.
In ASP.NET Framework, BinaryFormatter was used to automatically serialize session value contents. In order to serialize these with for use with the System.Web adapters, the serialization must be explicitly configured using ISessionKeySerializer implementations.
Out of the box, there is a simple JSON serializer that allows each session key to be registered to a known type using JsonSessionSerializerOptions:
RegisterKey<T>(string) - Registers a session key to a known type. This registration is required for correct serialization/deserialization. Missing registrations cause errors and prevent session access.:::code language="csharp" source="~/migration/fx-to-core/areas/session/samples/serialization/Program.cs" id="snippet_Serialization" :::
If more customization is needed, then ISessionKeySerializer can be implemented:
:::code language="csharp" source="/migration/fx-to-core/areas/session/samples/serialization/Program_Custom.cs" id="snippet_Serialization" :::
:::code language="csharp" source="/migration/fx-to-core/areas/session/samples/serialization/Program_Custom.cs" id="snippet_CustomSerializer" :::
[!NOTE] When using the
AddJsonSessionSerializerregistration pattern, there is no need to callAddSessionSerializeras it will automatically be added. If you only want to use a customimplementation, then you must manually add it.
Session support requires explicit activation. Configure it per-route or globally using ASP.NET Core metadata:
:::code language="csharp" source="~/migration/fx-to-core/areas/session/samples/remote/SomeController.cs" id="snippet_Controller" :::
:::code language="csharp" source="~/migration/fx-to-core/areas/session/samples/remote/Program.cs" id="snippet_RequireSystemWebAdapterSession" :::
Choose this approach when your migrated components don't need to share session data with your legacy application.
The Microsoft.Extensions.DependencyInjection.WrappedSessionExtensions.AddWrappedAspNetCoreSession extension method adds a wrapped ASP.NET Core session to work with the adapters. It uses the same backing store as xref:Microsoft.AspNetCore.Http.ISession while providing strongly-typed access.
Configuration for ASP.NET Core:
:::code language="csharp" source="~/migration/fx-to-core/areas/session/samples/wrapped/Program.cs" id="snippet_WrapAspNetCoreSession" :::
Your Framework application requires no changes.
For more information, see the wrapped session state sample app
Choose this approach when you need to share session state between your ASP.NET Framework and ASP.NET Core applications during incremental migration.
Remote app session enables communication between applications to retrieve and set session state by exposing an endpoint on the ASP.NET Framework app.
Complete the remote app setup instructions to connect your ASP.NET Core and ASP.NET Framework applications.
:::zone pivot="manual" ASP.NET Core configuration:
Call AddRemoteAppSession and AddJsonSessionSerializer to register known session item types:
:::code language="csharp" source="~/migration/fx-to-core/areas/session/samples/remote/Program.cs" id="snippet_RemoteConfiguration" :::
ASP.NET Framework configuration:
Add this change to Global.asax.cs:
:::code language="csharp" source="~/migration/fx-to-core/areas/session/samples/remote/Global.asax.cs":::
:::zone-end
:::zone pivot="aspire" When using Aspire, the configuration will be done via environment variables and are set by the AppHost. To enable remote session, the option must be enabled:
...
var coreApp = builder.AddProject<Projects.CoreApplication>("core")
.WithHttpHealthCheck()
.WaitFor(frameworkApp)
.WithIncrementalMigrationFallback(frameworkApp, options => options.RemoteSession = RemoteSession.Enabled);
...
:::zone-end
Readonly sessions retrieve session state without locking. The process uses a single GET request that returns session state and closes immediately.
Writeable sessions require additional steps:
GET request as readonly sessionsGET request open until the session completesPUT request to update state