ASP.NET do migracji przyrostowej IHttpModule ASP.NET Core

Moduły to typy, które implementują IHttpModule i są używane w ASP.NET Framework, aby podłączyć się do potoku żądania w różnych zdarzeniach. W aplikacji ASP.NET Core najlepiej przeprowadzić migrację do oprogramowania pośredniczącego. Jednak czasami nie można tego zrobić. Aby obsługiwać scenariusze migracji, w których wymagane są moduły i nie można ich przenieść do oprogramowania pośredniczącego, karty System.Web obsługują dodawanie ich do platformy ASP.NET Core.

Przykład IHttpModule

Aby obsługiwać moduły, wystąpienie HttpApplication musi być dostępne. Jeśli nie jest używany żaden niestandardowy HttpApplication , domyślny zostanie użyty do dodania modułów. Zdarzenia zadeklarowane w aplikacji niestandardowej (w tym Application_Start) zostaną zarejestrowane i odpowiednio uruchomione.

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
    }
  }
}

Migracja global.asax

Ta infrastruktura może służyć do migrowania użycia w Global.asax razie potrzeby. Źródło z Global.asax programu jest niestandardowe HttpApplication , a plik można uwzględnić w aplikacji ASP.NET Core. Ponieważ nosi nazwę Global, można użyć następującego kodu do zarejestrowania go:

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

Tak długo, jak logika w niej jest dostępna w ASP.NET Core, to podejście może służyć do przyrostowej migracji polegania na Global.asax ASP.NET Core.

Zdarzenia uwierzytelniania/autoryzacji

Aby zdarzenia uwierzytelniania i autoryzacji były uruchamiane w żądanym czasie, należy użyć następującego wzorca:

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

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

Jeśli nie zostanie to zrobione, zdarzenia będą nadal uruchamiane. Jednak będzie to w trakcie wywołania .UseSystemWebAdapters()metody .

Buforowanie modułów HTTP

Ponieważ moduły i aplikacje w programie ASP.NET Framework zostały przypisane do żądania, dla każdego żądania potrzebne jest nowe wystąpienie. Jednak ponieważ mogą być kosztowne do utworzenia, są one w puli przy użyciu metody ObjectPool<T>. Aby dostosować rzeczywisty okres istnienia HttpApplication wystąpień, można użyć puli niestandardowej:

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);
});

Dodatkowe zasoby