Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion docs/session-state/remote-session.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,18 @@

Remote app session state will enable communication between the ASP.NET Core and ASP.NET app and to retrieve the session state. This is enabled by exposing an endpoint on the ASP.NET app that can be queried to retrieve and set the session state.

# HttpSessionState serialization

The `System.Web.SessionState.HttpSessionState` object must be serialized for remote app session state to be enabled. This is accomplished through implementation of the type `Microsoft.AspNetCore.SysteWebAdapters.SessionState.Serialization.ISessionSerializer`, of which a default binary writer implementation is provided. This is added by the following code:

```csharp
builder.Services.AddSystemWebAdapters()
.AddSessionSerializer(options =>
{
// Customize session serialization here
});
```

## Configuration

In order to configure it, both the framework and core app must set an API key as well as register known app settings types. These properties are:
Expand Down Expand Up @@ -52,7 +64,7 @@ The framework equivalent would look like the following change in `Global.asax.cs

```csharp
Application.AddSystemWebAdapters()
.AddRemoteAppSession(
.AddJsonRemoteAppSession(
// Provide a strong API key that will be used to authenticate the request on the remote app for querying the session
options => options.ApiKey = "strong-api-key",
options =>
Expand Down
5 changes: 2 additions & 3 deletions docs/session-state/session.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@ The adapter infrastructure exposes two interfaces that can be used to implement
- `Microsoft.AspNetCore.SystemWebAdapters.ISessionState`: This describes the state of a session object. It is used as the backing of the `System.Web.SessionState.HttpSessionState` type.

## Serialization
Since the adapters provide the ability to work with strongly-typed session state, we must be able to serialize and deserialize types. This is accomplished through implementation of the type `Microsoft.AspnetCore.SysteWebAdapters.SessionState.Serialization.ISessionSerializer`, of which a JSON implementation is provided.
Since the adapters provide the ability to work with strongly-typed session state, we must be able to serialize and deserialize types. This is customized through the `Microsoft.AspNetCore.SystemWebAdapters.SessionState.Serialization.ISessionKeySerializer`.

Serialization and deserialization of session keys requires additional information which is configured via the `JsonSessionSerializerOptions`:
A default JSON implementation is provided that is configured via the `JsonSessionSerializerOptions`:

- `ThrowOnUnknownSessionKey` - Gets or sets if an unknown key should cause serialization to fail or if it will log a warning and ignore it.
- `RegisterKey<T>(string)` - Registers a session key to a known type. This is required in order to serialize/deserialize the session state correctly. If a key is found that there is no registration for, an error will be thrown and session will not be available.

To use the default JSON backed implementation, add a package reference to [Microsoft.AspNetCore.SystemWebAdapters.SessionState](https://www.nuget.org/packages/Microsoft.AspNetCore.SystemWebAdapters.SessionState) and add the following to the startup:
Expand Down
2 changes: 1 addition & 1 deletion samples/MvcApp/Global.asax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protected void Application_Start()

Application.AddSystemWebAdapters()
.AddProxySupport(options => options.UseForwardedHeaders = true)
.AddRemoteAppSession(
.AddJsonRemoteAppSession(
ConfigureRemoteServiceOptions,
options => ClassLibrary.RemoteServiceUtils.RegisterSessionKeys(options.KnownKeys))
.AddRemoteAppAuthentication(o => ConfigureRemoteServiceOptions(o.RemoteServiceOptions));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Microsoft.AspNetCore.SystemWebAdapters.SessionState.RemoteSession;
using Microsoft.AspNetCore.SystemWebAdapters.SessionState.Serialization;

namespace Microsoft.AspNetCore.SystemWebAdapters;

public static class JsonRemoteAppSessionStateExtensions
{
public static ISystemWebAdapterBuilder AddJsonRemoteAppSession(this ISystemWebAdapterBuilder builder, Action<RemoteAppSessionStateOptions> configureRemote, Action<JsonSessionSerializerOptions> configureSerializer)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}

if (configureRemote is null)
{
throw new ArgumentNullException(nameof(configureRemote));
}

if (configureSerializer is null)
{
throw new ArgumentNullException(nameof(configureSerializer));
}

var serializerOptions = new JsonSessionSerializerOptions();
configureSerializer(serializerOptions);

var keySerializer = new JsonSessionKeySerializer(serializerOptions);

return builder.AddRemoteAppSession(configureRemote, keySerializer);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.SystemWebAdapters;

public static class RemoteAppSessionStateExtensions
{
public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapterBuilder builder, Action<RemoteAppSessionStateOptions> configureRemote, Action<JsonSessionSerializerOptions> configureSerializer)
public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapterBuilder builder, Action<RemoteAppSessionStateOptions> configureRemote, ISessionKeySerializer keySerializer)
{
if (builder is null)
{
Expand All @@ -21,22 +21,39 @@ public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapte
throw new ArgumentNullException(nameof(configureRemote));
}

if (configureSerializer is null)
if (keySerializer is null)
{
throw new ArgumentNullException(nameof(configureSerializer));
throw new ArgumentNullException(nameof(keySerializer));
}

var options = new RemoteAppSessionStateOptions();
configureRemote(options);

// We don't want to throw by default on the .NET Framework side as then the error won't be easily visible in the ASP.NET Core app
var serializerOptions = new JsonSessionSerializerOptions();
configureSerializer(serializerOptions);
var serializerOptions = new SessionSerializerOptions { ThrowOnUnknownSessionKey = false };
var serializer = new BinarySessionSerializer(keySerializer, serializerOptions);

return builder.AddRemoteAppSession(configureRemote, serializer);
}

public static ISystemWebAdapterBuilder AddRemoteAppSession(this ISystemWebAdapterBuilder builder, Action<RemoteAppSessionStateOptions> configureRemote, ISessionSerializer serializer)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}

if (configureRemote is null)
{
throw new ArgumentNullException(nameof(configureRemote));
}

if (serializer is null)
{
throw new ArgumentNullException(nameof(serializer));
}

var keySerializer = new JsonSessionKeySerializer(serializerOptions);
var serializer = new BinarySessionSerializer(keySerializer, new SessionSerializerOptions { ThrowOnUnknownSessionKey = false });
var remoteOptions = new RemoteAppSessionStateOptions();
configureRemote(remoteOptions);

builder.Modules.Add(new RemoteSessionModule(options, new InMemoryLockedSessions(serializer), serializer));
builder.Modules.Add(new RemoteSessionModule(remoteOptions, new InMemoryLockedSessions(serializer), serializer));

return builder;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using Microsoft.AspNetCore.SystemWebAdapters.SessionState.Serialization;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;

namespace Microsoft.AspNetCore.SystemWebAdapters;

public static class JsonSessionSerializerExtensions
{
public static ISystemWebAdapterBuilder AddJsonSessionSerializer(this ISystemWebAdapterBuilder builder, Action<JsonSessionSerializerOptions>? configure = null)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}

builder.AddSessionSerializer();
builder.Services.TryAddSingleton<ISessionKeySerializer, JsonSessionKeySerializer>();

var options = builder.Services.AddOptions<JsonSessionSerializerOptions>();

if (configure is not null)
{
options.Configure(configure);
}

return builder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,4 @@ public static ISystemWebAdapterBuilder AddSessionSerializer(this ISystemWebAdapt

return builder;
}

public static ISystemWebAdapterBuilder AddJsonSessionSerializer(this ISystemWebAdapterBuilder builder, Action<JsonSessionSerializerOptions>? configure = null)
{
if (builder is null)
{
throw new ArgumentNullException(nameof(builder));
}

builder.AddSessionSerializer();
builder.Services.TryAddSingleton<ISessionKeySerializer, JsonSessionKeySerializer>();

var options = builder.Services.AddOptions<JsonSessionSerializerOptions>();

if (configure is not null)
{
options.Configure(configure);
}

return builder;
}
}

This file was deleted.