Share via


ASP.NET per ASP.NET migrazione incrementale di IHttpModule core

I moduli sono tipi che implementano IHttpModule e vengono usati in ASP.NET Framework per eseguire l'hook nella pipeline di richiesta in vari eventi. In un'applicazione ASP.NET Core, è consigliabile eseguirne la migrazione al middleware. Tuttavia, ci sono momenti in cui questo non può essere fatto. Per supportare scenari di migrazione in cui sono necessari i moduli e non possono essere spostati nel middleware, gli adapter System.Web supportano l'aggiunta di tali moduli a ASP.NET Core.

Esempio di IHttpModule

Per supportare i moduli, è necessario che sia disponibile un'istanza di HttpApplication . Se non viene usata alcuna opzione personalizzata HttpApplication , ne verrà usata una predefinita per aggiungere i moduli. Gli eventi dichiarati in un'applicazione personalizzata (incluso Application_Start) verranno registrati ed eseguiti di conseguenza.

using System.Web;
using Microsoft.AspNetCore.OutputCaching;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddSystemWebAdapters()
    .AddHttpApplication<MyApp>(options =>
    {
        // Size of pool for HttpApplication instances. Should be what the expected concurrent requests will be
        options.PoolSize = 10;

        // Register a module (optionally) by name
        options.RegisterModule<MyModule>("MyModule");
    });

// Only available in .NET 7+
builder.Services.AddOutputCache(options =>
{
    options.AddHttpApplicationBasePolicy(_ => new[] { "browser" });
});

var app = builder.Build();

app.UseAuthentication();
app.UseAuthenticationEvents();

app.UseAuthorization();
app.UseAuthorizationEvents();

app.UseSystemWebAdapters();
app.UseOutputCache();

app.MapGet("/", () => "Hello World!")
    .CacheOutput();

app.Run();

class MyApp : HttpApplication
{
    protected void Application_Start()
    {
    }

    public override string? GetVaryByCustomString(System.Web.HttpContext context, string custom)
    {
        // Any custom vary-by string needed

        return base.GetVaryByCustomString(context, custom);
    }
}

class MyModule : IHttpModule
{
  public void Dispose()
  {
  }

  public void Init(HttpApplication application)
  {
    application.BeginRequest += (s, e) =>
    {
      // Handle events at the beginning of a request
    }

    application.AuthorizeRequest += (s, e) =>
    {
      // Handle events that need to be authorized
    }
  }
}

Migrazione global.asax

Questa infrastruttura può essere usata per eseguire la migrazione dell'utilizzo di Global.asax , se necessario. L'origine da Global.asax è personalizzata HttpApplication e il file può essere incluso in un'applicazione ASP.NET Core. Poiché è denominato Global, è possibile usare il codice seguente per registrarlo:

builder.Services.AddSystemWebAdapters()
    .AddHttpApplication<Global>()

Purché la logica all'interno sia disponibile in ASP.NET Core, questo approccio può essere usato per eseguire la migrazione incrementale della Global.asax dipendenza da ASP.NET Core.

Eventi di autenticazione/autorizzazione

Affinché gli eventi di autenticazione e autorizzazione vengano eseguiti al momento desiderato, è necessario usare il modello seguente:

app.UseAuthentication();
app.UseAuthenticationEvents();

app.UseAuthorization();
app.UseAuthorizationEvents();

Se questa operazione non viene eseguita, gli eventi verranno comunque eseguiti. Tuttavia, sarà durante la chiamata di .UseSystemWebAdapters().

Pool di moduli HTTP

Poiché i moduli e le applicazioni in ASP.NET Framework sono stati assegnati a una richiesta, è necessaria una nuova istanza per ogni richiesta. Tuttavia, poiché possono essere costosi da creare, vengono inseriti in pool usando ObjectPool<T>. Per personalizzare la durata effettiva delle HttpApplication istanze, è possibile usare un pool personalizzato:

services.TryAddSingleton<ObjectPool<HttpApplication>>(sp =>
{
  // Recommended to use the in-built policy as that will ensure everything is initialized correctly and is not intended to be replaced
  var policy = sp.GetRequiredService<IPooledOjbectPolicy<HttpApplication>>()

  // Can use any provider needed
  var provider = new DefaultObjectPoolProvider();

  // Use the provider to create a custom pool that will then be used for the application.
  return provider.Create(policy);
});

Risorse aggiuntive