ASP.NET Core 증분 IHttpModule 마이그레이션에 ASP.NET

모듈은 다양한 이벤트에서 요청 파이프라인에 연결하기 위해 ASP.NET Framework에서 구현 IHttpModule 하고 사용하는 형식입니다. ASP.NET Core 애플리케이션에서는 미들웨어로 마이그레이션하는 것이 가장 좋습니다. 그러나 이 작업을 수행할 수 없는 경우가 있습니다. 모듈이 필요하고 미들웨어로 이동할 수 없는 마이그레이션 시나리오를 지원하기 위해 System.Web 어댑터는 ASP.NET Core에 추가하도록 지원합니다.

IHttpModule 예제

모듈을 지원하려면 인스턴스 HttpApplication 를 사용할 수 있어야 합니다. 사용자 지정 HttpApplication 을 사용하지 않으면 모듈을 추가하는 데 기본값이 사용됩니다. 사용자 지정 애플리케이션에 선언된 이벤트(포함 Application_Start)가 등록되고 그에 따라 실행됩니다.

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

builder.Services.AddAuthentication();
builder.Services.AddAuthorization();

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

    public void Dispose()
    {
    }
}

Global.asax 마이그레이션

이 인프라는 필요한 경우 사용량을 Global.asax 마이그레이션하는 데 사용할 수 있습니다. 원본 Global.asax 은 사용자 지정 HttpApplication 이며 ASP.NET Core 애플리케이션에 파일을 포함할 수 있습니다. 이름이 지정 Global되므로 다음 코드를 사용하여 등록할 수 있습니다.

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

ASP.NET Core에서 논리를 사용할 수 있는 한 이 방법을 사용하여 ASP.NET Core에 대한 Global.asax 의존도를 증분 방식으로 마이그레이션할 수 있습니다.

인증/권한 부여 이벤트

인증 및 권한 부여 이벤트를 원하는 시간에 실행하려면 다음 패턴을 사용해야 합니다.

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

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

이 작업이 수행되지 않으면 이벤트가 계속 실행됩니다. 그러나 호출하는 동안 .UseSystemWebAdapters()에 해당합니다.

HTTP 모듈 풀링

ASP.NET Framework의 모듈과 애플리케이션이 요청에 할당되었으므로 각 요청에 새 인스턴스가 필요합니다. 그러나 만드는 데 비용이 많이 들 수 있으므로 ObjectPool<T>. 인스턴스의 HttpApplication 실제 수명을 사용자 지정하기 위해 사용자 지정 풀을 사용할 수 있습니다.

builder.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<IPooledObjectPolicy<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);
});

추가 리소스