WEBA Bausteine

Für Webanwendungen gibt es spezielle Anforderungen, die berücksichtigt werden müssen. Für jeden Client wird eine Session gestartet, in dem ein- oder mehrmals ein Request angefordert wird. Für die Verarbeitung eines Request steht auf dem Webserver aber nur eine begrenzte Anzahl Ressourcen (Prozesse, Threads bzw. Zum Wörterbuch hinzufügen) zur Verfügung, die von dem Internet Information Server (IIS) für die unterschiedlichen Requests wiederverwendet werden. Dadurch können einzelne Requests innerhalb einer Session in unterschiedlichen AppDomains, Prozessen oder sogar auf unterschiedlichen Rechnern ausgeführt werden.

Außerdem werden je nach Programmiermodell (ASP.NET WebForms, MVC, …) für die Implementierung bestimmte Basisklassen vorausgesetzt, welche sich um die Aufbereitung des Ergebnisses (i.e. rendering) kümmern. An hiervon abgeleiteten Klassen müssen dann bestimmte Methoden implementiert bzw. übersteuert werden, welche von IIS für den jeweiligen Request aufgerufen werden.

Deswegen wird für WEBA Bausteine keine Methode RunImplementation erzeugt, welche für die Implementierung übersteuert werden muss. Statt dessen wird in der Basisklasse eine statische Methode GetSessionInstance erzeugt, welche verwendet werden kann, um die Instanz während der Verarbeitung eines Requests zu liefern:

namespace WebApp
{
    public class MySessionModule: HL.Modules.Weba.Twonly.HlWebaTest
    {
...
        public static MySessionModule Instance => GetSessionInstance<MySessionModule>();
...
Für Bausteine vom Typ WEBA gelten die gleichen Regeln für die Implementierungsspezifikation, allerdings muss als Implementierungstyp ASPCLR eingetragen werden.

Web.config

Dieser Abschnitt gilt nur für ASP.NET (e.g. .NET Framework). Für ASP.NET Core (e.g. .NET 6.0 und später) siehe den Abschnitt ASP.NET Core

Damit die Infrastruktur in der Lage ist, die richtige Instanz zu erzeugen und für die Verarbeitung eines Requests zur Verfügung zu stellen, muss die Implementierungsklasse in der Web.config als sog. HTTP Module eingetragen werden. Je nachdem, ob die Web-Anwendung im sog. Classic Mode oder Intergrated Mode läuft, muss der Eintrag an unterschiedlichen Stellen erfolgen:

Classic.xml
  <system.web>
    <httpModules>
      <add type="WebApp.MySessionModule" name="HlWebaTestSessionModule" />
    </httpModules>
  </system.web>
Intergrated.xml
  <system.webServer>
    <modules>
      <add type="WebApp.MySessionModule" name="HlWebaTestSessionModule" />
    </modules>
  </system.webServer>
Wenn das TAA Support Package für Visual Studio installiert ist, wird dieser Eintrag in der Web.config automatisch vorgenommen, und ggf. bei Änderungen auch angepasst.

Implementierung

Die Infrastruktur legt beim jedem Request eine Instanz dieser Implementierungsklasse an. Wenn der Request beendet wird, werden die Daten (z.B. Objekteinhalte) für die Instanz gesichert und beim nächsten Request verwendet, um die neue Instanz zu initialisieren. Bevor ASP.NET dann die für Implementierung des Requests ermittelte Methode auslöst, wird die Methode BeginRequest an der Instanz der Implementierungsklasse ausgelöst. Nachdem ASP.NET die Kontrolle zurückbekommt, und bevor die Daten gesichert werden, wird die Methode EndRequest an der Instanz der Implementierungsklasse ausgelöst. Diese beiden Methoden können ggf. übersteuert werden, um entsprechend reagieren zu können.

Da es sich bei Bausteinen vom Typ WEBA um Einstiegsbausteine handelt, können hier auch die Eigenschaften und Methoden, welche hier beschrieben sind, verwendet werden. Zusätzlich stehen die nachfolgend beschriebenen Eigenschaften und Methoden zur Verfügung.

Eigenschaften

protected Boolean IsReentry { get; };

Liefert false für die 1. Anforderung in einer Sitzung, true für alle nachfolgenden.

Methoden

protected static T GetSessionInstance<T>()
	where T : SessionModule;

Liefert die für die aktuelle Sitzung zuständige Instanz der Klasse der dieser Web-Verbindungsbaustein implementiert

protected virtual void RequestBegin();

Wird am Anfang jede einzelne HTTP-Anforderung ausgelöst.

protected virtual void RequestEnd();

Wird am Ende jede einzelne HTTP-Anforderung ausgelöst

public void RestartSession(HttpContext httpContext);

Diese Methode kann verwendet werden1), um die aktuelle SessionModule-Instanz neu zu initialisieren, um z.B. geänderte Eigenschaften zu berücksichtigen. Die aktuelle HttpContext-Instanz muss explizit übergeben werden.

Für ASP.NET Core steht die Eigenschaft HttpContext.Current nicht mehr zur Verfügung. Siehe hier für die unterschiedliche Möglichkeiten, um auf die aktuelle HttpContext Instanz zu zu greifen.

public void RestartSession();

Ruft die Methode RestartSession mit HttpContext.Current auf. Diese Methode kann nur in .NET Framework verwendet werden.

ASP.NET Core

Dieser Abschnitt ist in Bearbeitung, und kann ggf. noch angepasst werden.

Für die Integration von HTTP Module und HTTP Handler unter ASP.NET Core spielt die Web.config keine Rolle mehr, sondern die HTTP Pipeline wird mittels einer Reihe spezieller Extension-Methoden konfiguriert (Details). Für ASP.NET Core gibt es eine Klasse SessionModuleExtensions2), in der Extension-Methoden für die Integration eines TAA SessionModule in die Middleware definiert sind.

Session State

Diese Methoden können da verwendet werden wo Session State konfiguriert wird.

public static IServiceCollection AddSessionModule<T>(this IServiceCollection services, Action<SessionOptions> configure = null)
	where T : SessionModule

Fügt Dienste hinzu, die für die TAA SessionModule-Unterstützung benötigt werden. Dazu gehören auch die Dienste, die für den session state erforderlich sind. Diese Methode kann anstatt AddSession(IServiceCollection, Action<SessionOptions>) verwendet werden.

public static IApplicationBuilder UseSessionModule<T>(this IApplicationBuilder builder, SessionOptions options = null)
	where T : SessionModule

Fügt der Anforderungspipeline der Anwendung die TAA SessionModule-Middleware hinzu. Dazu gehört auch die Middleware, die für den session state erforderlich ist. Diese Methode kann anstatt UseSession(IApplicationBuilder, Action<SessionOptions>) verwendet werden.

Beispiel

Nachfolgend ein Beispiel, wie diese Methoden bei der Konfiguration eine ASP.NET Core MVC Anwendung verwendet werden:

Program.cs
public static void Main(string[] args)
{
	var builder = WebApplication.CreateBuilder(args);
 
	// Add services to the container.
	builder.Services.AddControllersWithViews();
 
	builder.Services.AddSessionModule<WebaModule>();
 
	var app = builder.Build();
 
	// Configure the HTTP request pipeline.
	if (!app.Environment.IsDevelopment()) {
		app.UseExceptionHandler("/Home/Error");
		// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
		app.UseHsts();
	}
 
	app.UseHttpsRedirection();
	app.UseStaticFiles();
 
	app.UseRouting();
 
	app.UseAuthorization();
 
	app.UseSessionModule<WebaModule>();
 
	app.MapControllerRoute(
				name: "default",
				pattern: "{controller=Home}/{action=Index}/{id?}");
 
	app.Run();
}

ASP.NET Core Blazor

WEBA-Bausteine können auch, aber nur Serverseitig, in eine ASP.NET Core Blazor Anwendung verwendet werden3). Blazor verwendet aber kein session state, sondern die Benutzerdaten bzw. state werden Serverseitig in ein sog. Circuit vorgehalten (Details). Daher können die Methoden für Session State nicht verwendet werden, und gibt es für Blazor eigene Extension Methoden für die Integration eines SessionModule-Instanz mit einem Circuit:

public static IServerSideBlazorBuilder AddCircuitSessionModule<T>(this IServerSideBlazorBuilder builder)
	where T : SessionModule, new()

Fügt Dienste hinzu, die für die TAA SessionModule Unterstützung in eine ASP.NET Core Blazor Anwendung benötigt werden.

public static IApplicationBuilder UseCircuitSessionModule<T>(this IApplicationBuilder builder)
	where T : SessionModule, new()

Fügt der Anforderungspipeline der ASP.NET Core Blazor Anwendung die TAA SessionModule Middleware hinzu.

Die Lebensdauer einer SessionModule-Instanz ist mit der Lebensdauer des Circuit verknüpft. Beim Instanziieren eines Circuit wird auch eine SessionModule angelegt und wird (intern) die Anmeldung bei der TAA vorgenommen. Sobald die Circuit-Instanz aufgeräumt wird, wird auch die SessionModule-Instanz bei der TAA abgemeldet, und aufgeräumt.

Beispiel

Nachfolgend ein Beispiel, wie diese Methoden bei der Konfiguration eine ASP.NET Core Blazor Anwendung verwendet werden:

Program.cs
public static void Main(string[] args)
{
	// Add services to the container.
	var builder = WebApplication.CreateBuilder(args);
	builder.Services.AddRazorComponents()
		.AddInteractiveServerComponents()
		.AddCircuitSessionModule<WebaModule>();
 
	var app = builder.Build();
 
	// Configure the HTTP request pipeline.
	if (!app.Environment.IsDevelopment()) {
		app.UseExceptionHandler("/Error");
		// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
		app.UseHsts();
	}
 
	app.UseHttpsRedirection();
 
	app.UseStaticFiles();
	app.UseAntiforgery();
 
	app.UseCircuitSessionModule<WebaModule>();
 
	app.MapRazorComponents<App>()
		.AddInteractiveServerRenderMode();
 
	app.Run();
}

dependency injection

Damit auch in den Blazor Komponenten mittels dependency injection auf die SessionModule-Instanz zugegriffen werden kann, wird eine Service Komponente CircuitSessionModuleAccessor<T> registriert:

public sealed class CircuitSessionModuleAccessor<T>
	where T : SessionModule, new()
{
	public T? GetSessionInstance();
	public async Task<T?> GetSessionInstanceAsync();
}

Als Typargument T wird der Name der Implementierungsklasse für das WEBA-Modul übergeben. e.g. CircuitSessionModuleAccessor<WebaModule>.

public T? GetSessionInstance()

Liefert die, für das aktuelle Circuit, zuständige Instanz der Implementierungsklasse des WEBA-Moduls.

public async Task<T?> GetSessionInstanceAsync()

Kreiert ein Task<T?> der, für das aktuelle Circuit, die zuständige Instanz der Implementierungsklasse des WEBA-Moduls liefert.

Beispiel

Nachfolgend ein Beispiel, wie diese Service verwendet wird:

Home.razor
@page "/"
@rendermode InteractiveServer
@inject CircuitSessionModuleAccessor<WebaModule> accessor;
 
<PageTitle>Home</PageTitle>
 
<h1>Hello, world!</h1>
 
Welcome to your new app.
 
@if (Name == null) {
    <p>Waiting for SessionModule</p>
}
else {
    <p>SessionModule: @Name</p>
}
 
@code {
    private string Name = null;
 
    protected override async Task OnInitializedAsync()
    {
        var modl = await accessor.GetSessionInstanceAsync();
        Name = modl?.Name;
    }
}
1) , 2)
R10.01
3)
R26.00
dotnet:native:sessionmodule · Zuletzt geändert: 04.09.2025 13:34

Copyright © 1992-2025 TeamWiSE Gesellschaft für Softwaretechnik mbH         Adressen |  Kontakt |  AGB |  Datenschutzerklärung |  Impressum