HTTP 처리기 및 모듈을 ASP.NET Core 미들웨어로 마이그레이션

이 문서에서는 system.webserver에서 ASP.NET Core 미들웨어로기존 ASP.NET HTTP 모듈 및 처리기를 마이그레이션하는 방법을 보여줍니다.

다시 방문한 모듈 및 처리기

ASP.NET Core 미들웨어로 진행하기 전에 먼저 HTTP 모듈 및 처리기의 작동 방식을 요약하겠습니다.

모듈 처리기

처리기는 다음과 같습니다.

  • IHttpHandler를 구현하는 클래스

  • 지정된 파일 이름 또는 확장명(예: .report)을 사용하여 요청을 처리하는 데 사용됩니다.

  • Web.config 구성됨

모듈은 다음과 같습니다.

  • IHttpModule을 구현하는 클래스

  • 모든 요청에 대해 호출됩니다.

  • 단락 가능(요청의 추가 처리 중지)

  • HTTP 응답에 추가하거나 직접 만들 수 있습니다.

  • Web.config 구성됨

모듈이 들어오는 요청을 처리하는 순서는 다음을 통해 결정됩니다.

  1. ASP.NET 발생한 계열 이벤트(예: BeginRequestAuthenticateRequest )입니다. 전체 목록을 보려면 System.Web.HttpApplication을 참조하세요. 각 모듈은 하나 이상의 이벤트에 대한 처리기를 만들 수 있습니다.

  2. 동일한 이벤트의 경우 Web.config 에서 구성 된 순서입니다.

모듈 외에도 전역 global.asax 파일에 수명 주기 이벤트에 대 한 처리기를 추가할 수 있습니다. 이러한 처리기는 구성 된 모듈의 처리기 다음에 실행 됩니다.

처리기 및 모듈에서 미들웨어로

미들웨어는 HTTP 모듈 및 처리기 보다 간단 합니다.

  • 모듈, 처리기, global.asax, Web.config (IIS 구성 제외) 및 응용 프로그램 수명 주기가 사라졌습니다.

  • 미들웨어에서 모듈 및 처리기의 역할을 모두 가져왔습니다.

  • 미들웨어는 Web.config 아닌 코드를 사용 하 여 구성 됩니다.

  • 파이프라인 분기 를 사용 하 여 URL 뿐만 아니라 요청 헤더, 쿼리 문자열 등에 따라 특정 미들웨어에 요청을 보낼 수 있습니다.
  • 파이프라인 분기 를 사용 하 여 URL 뿐만 아니라 요청 헤더, 쿼리 문자열 등에 따라 특정 미들웨어에 요청을 보낼 수 있습니다.

미들웨어는 모듈과 매우 유사 합니다.

미들웨어와 모듈은 다른 순서로 처리 됩니다.

권한 부여 미들웨어 단기는 권한이 없는 사용자에 대 한 요청을 담당 합니다. MVC 미들웨어는 인덱스 페이지에 대 한 요청을 허용 하 고 처리 합니다. 판매 보고서에 대한 요청은 사용자 지정 보고서 미들웨어에서 허용 및 처리됩니다.

위의 이미지에서 인증 미들웨어가 요청을 단락(short-circuit)한 방법에 유의하세요.

모듈 코드를 미들웨어로 마이그레이션

기존 HTTP 모듈은 다음과 유사합니다.

// ASP.NET 4 module

using System;
using System.Web;

namespace MyApp.Modules
{
    public class MyModule : IHttpModule
    {
        public void Dispose()
        {
        }

        public void Init(HttpApplication application)
        {
            application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
            application.EndRequest += (new EventHandler(this.Application_EndRequest));
        }

        private void Application_BeginRequest(Object source, EventArgs e)
        {
            HttpContext context = ((HttpApplication)source).Context;

            // Do something with context near the beginning of request processing.
        }

        private void Application_EndRequest(Object source, EventArgs e)
        {
            HttpContext context = ((HttpApplication)source).Context;

            // Do something with context near the end of request processing.
        }
    }
}

미들웨어 페이지에 표시된 것처럼 ASP.NET Core 미들웨어는 를 가져와 를 Invoke HttpContext 반환하는 메서드를 노출하는 Task 클래스입니다. 새 미들웨어는 다음과 같습니다.

// ASP.NET Core middleware

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MyApp.Middleware
{
    public class MyMiddleware
    {
        private readonly RequestDelegate _next;

        public MyMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            // Do something with context near the beginning of request processing.

            await _next.Invoke(context);

            // Clean up.
        }
    }

    public static class MyMiddlewareExtensions
    {
        public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyMiddleware>();
        }
    }
}

위의 미들웨어 템플릿은 미들웨어 작성섹션에서 가져온 것입니다.

MyMiddlewareExtensions 도우미 클래스를 사용하면 클래스에서 미들웨어를 더 쉽게 구성할 수 Startup 있습니다. UseMyMiddleware메서드는 미들웨어 클래스를 요청 파이프라인에 추가합니다. 미들웨어에 필요한 서비스는 미들웨어의 생성자에 삽입됩니다.

예를 들어 사용자에게 권한이 없는 경우 모듈에서 요청을 종료할 수 있습니다.

// ASP.NET 4 module that may terminate the request

private void Application_BeginRequest(Object source, EventArgs e)
{
    HttpContext context = ((HttpApplication)source).Context;

    // Do something with context near the beginning of request processing.

    if (TerminateRequest())
    {
        context.Response.End();
        return;
    }
}

미들웨어는 파이프라인의 다음 미들웨어에서 를 호출하지 않고 이를 Invoke 처리합니다. 응답이 파이프라인을 통해 다시 돌아갈 때 이전 미들웨어가 계속 호출되기 때문에 요청이 완전히 종료되지는 않습니다.

// ASP.NET Core middleware that may terminate the request

public async Task Invoke(HttpContext context)
{
    // Do something with context near the beginning of request processing.

    if (!TerminateRequest())
        await _next.Invoke(context);

    // Clean up.
}

모듈의 기능을 새 미들웨어로 마이그레이션하면 HttpContext ASP.NET Core에서 클래스가 크게 변경되어 코드가 컴파일되지 않을 수 있습니다. 나중에새 ASP.NET Core HttpContext로 마이그레이션하는 방법을 살펴보겠습니다.

요청 파이프라인으로 모듈 삽입 마이그레이션

HTTP 모듈은 일반적으로 Web.config 사용하여 요청 파이프라인에 추가됩니다.

<?xml version="1.0" encoding="utf-8"?>
<!--ASP.NET 4 web.config-->
<configuration>
  <system.webServer>
    <modules>
      <add name="MyModule" type="MyApp.Modules.MyModule"/>
    </modules>
  </system.webServer>
</configuration>

클래스의 요청 파이프라인에 새 미들웨어를 추가하여 이를 변환합니다. Startup

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMyMiddleware();

    app.UseMyMiddlewareWithParams();

    var myMiddlewareOptions = Configuration.GetSection("MyMiddlewareOptionsSection").Get<MyMiddlewareOptions>();
    var myMiddlewareOptions2 = Configuration.GetSection("MyMiddlewareOptionsSection2").Get<MyMiddlewareOptions>();
    app.UseMyMiddlewareWithParams(myMiddlewareOptions);
    app.UseMyMiddlewareWithParams(myMiddlewareOptions2);

    app.UseMyTerminatingMiddleware();

    // Create branch to the MyHandlerMiddleware. 
    // All requests ending in .report will follow this branch.
    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".report"),
        appBranch => {
            // ... optionally add more middleware to this branch
            appBranch.UseMyHandler();
        });

    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".context"),
        appBranch => {
            appBranch.UseHttpContextDemoMiddleware();
        });

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

새 미들웨어를 삽입하는 파이프라인의 정확한 지점은 모듈( , 등)으로 처리된 BeginRequest EndRequest 이벤트와 Web.config 모듈 목록에서의 순서에 따라 달라집니다.

앞에서 언급했듯이 ASP.NET Core에는 애플리케이션 수명 주기가 없으며 미들웨어에서 응답이 처리되는 순서는 모듈에서 사용하는 순서와 다릅니다. 이렇게 하면 순서 결정을 더 어려울 수 있습니다.

정렬이 문제가 되는 경우 독립적으로 정렬할 수 있는 여러 미들웨어 구성 요소로 모듈을 분할할 수 있습니다.

미들웨어로 처리기 코드 마이그레이션

HTTP 처리기는 다음과 같습니다.

// ASP.NET 4 handler

using System.Web;

namespace MyApp.HttpHandlers
{
    public class MyHandler : IHttpHandler
    {
        public bool IsReusable { get { return true; } }

        public void ProcessRequest(HttpContext context)
        {
            string response = GenerateResponse(context);

            context.Response.ContentType = GetContentType();
            context.Response.Output.Write(response);
        }

        // ...

        private string GenerateResponse(HttpContext context)
        {
            string title = context.Request.QueryString["title"];
            return string.Format("Title of the report: {0}", title);
        }

        private string GetContentType()
        {
            return "text/plain";
        }
    }
}

ASP.NET Core 프로젝트에서 다음과 유사한 미들웨어로 변환 합니다.

// ASP.NET Core middleware migrated from a handler

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace MyApp.Middleware
{
    public class MyHandlerMiddleware
    {

        // Must have constructor with this signature, otherwise exception at run time
        public MyHandlerMiddleware(RequestDelegate next)
        {
            // This is an HTTP Handler, so no need to store next
        }

        public async Task Invoke(HttpContext context)
        {
            string response = GenerateResponse(context);

            context.Response.ContentType = GetContentType();
            await context.Response.WriteAsync(response);
        }

        // ...

        private string GenerateResponse(HttpContext context)
        {
            string title = context.Request.Query["title"];
            return string.Format("Title of the report: {0}", title);
        }

        private string GetContentType()
        {
            return "text/plain";
        }
    }

    public static class MyHandlerExtensions
    {
        public static IApplicationBuilder UseMyHandler(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyHandlerMiddleware>();
        }
    }
}

이 미들웨어는 모듈에 해당 하는 미들웨어와 매우 비슷합니다. 여기에는에 대 한 호출이 없다는 점만 다릅니다 _next.Invoke(context) . 이는 처리기가 요청 파이프라인의 끝에 있기 때문에 의미가 있으므로 호출할 다음 미들웨어가 없습니다.

요청 파이프라인으로 처리기 삽입 마이그레이션

HTTP 처리기 구성은 Web.config 에서 수행 되며 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<!--ASP.NET 4 web.config-->
<configuration>
  <system.webServer>
    <handlers>
      <add name="MyHandler" verb="*" path="*.report" type="MyApp.HttpHandlers.MyHandler" resourceType="Unspecified" preCondition="integratedMode"/>
    </handlers>
  </system.webServer>
</configuration>

Startup모듈에서 변환 된 미들웨어와 마찬가지로 클래스의 요청 파이프라인에 새 처리기 미들웨어를 추가 하 여이를 변환할 수 있습니다. 이 방법의 문제는 새 처리기 미들웨어에 모든 요청을 전송 한다는 것입니다. 그러나 지정 된 확장을 포함 하는 요청만 미들웨어에 도달 하려고 합니다. 그러면 HTTP 처리기와 동일한 기능을 제공 합니다.

한 가지 해결 방법은 확장 메서드를 사용 하 여 지정 된 확장명을 가진 요청의 파이프라인을 분기 하는 것입니다 MapWhen . 다른 미들웨어를 추가 하는 것과 같은 방법으로이 작업을 수행 합니다 Configure .

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
        app.UseBrowserLink();
    }
    else
    {
        app.UseExceptionHandler("/Home/Error");
    }

    app.UseMyMiddleware();

    app.UseMyMiddlewareWithParams();

    var myMiddlewareOptions = Configuration.GetSection("MyMiddlewareOptionsSection").Get<MyMiddlewareOptions>();
    var myMiddlewareOptions2 = Configuration.GetSection("MyMiddlewareOptionsSection2").Get<MyMiddlewareOptions>();
    app.UseMyMiddlewareWithParams(myMiddlewareOptions);
    app.UseMyMiddlewareWithParams(myMiddlewareOptions2);

    app.UseMyTerminatingMiddleware();

    // Create branch to the MyHandlerMiddleware. 
    // All requests ending in .report will follow this branch.
    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".report"),
        appBranch => {
            // ... optionally add more middleware to this branch
            appBranch.UseMyHandler();
        });

    app.MapWhen(
        context => context.Request.Path.ToString().EndsWith(".context"),
        appBranch => {
            appBranch.UseHttpContextDemoMiddleware();
        });

    app.UseStaticFiles();

    app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=Home}/{action=Index}/{id?}");
    });
}

MapWhen 는 다음 매개 변수를 사용 합니다.

  1. 을 사용 하 HttpContexttrue 요청을 분기 아래로 이동 해야 하는 경우를 반환 하는 람다입니다. 즉, 확장 뿐만 아니라 요청 헤더, 쿼리 문자열 매개 변수 등에서 요청을 분기할 수 있습니다.

  2. 을 사용 하 IApplicationBuilder 고 분기에 대 한 모든 미들웨어를 추가 하는 람다입니다. 즉, 처리기 미들웨어 앞에 있는 분기에 미들웨어를 더 추가할 수 있습니다.

모든 요청에서 분기가 호출되기 전에 파이프라인에 미들웨어가 추가되었습니다. 분기는 영향을 미치지 않습니다.

옵션 패턴을 사용하여 미들웨어 옵션 로드

일부 모듈 및 처리기에는 Web.config 에 저장되는 구성 옵션이 있습니다. 그러나 ASP.NET Core에서는 Web.config 대신 새 구성 모델이 사용됩니다.

구성 시스템은 이 문제를 해결하기 위해 다음과 같은 옵션을 제공합니다.

  • 다음 섹션에표시된 것처럼 미들웨어에 옵션을 직접 삽입합니다.

  • 옵션 패턴를 사용합니다.

  1. 미들웨어 옵션을 보관할 클래스를 만듭니다. 예를 들면 다음과 같습니다.

    public class MyMiddlewareOptions
    {
        public string Param1 { get; set; }
        public string Param2 { get; set; }
    }
    
  2. 옵션 값 저장

    구성 시스템을 사용하면 원하는 위치에 옵션 값을 저장할 수 있습니다. 그러나 대부분의 appsettings.json 사이트에서는 를 사용하므로 다음 방법을 사용합니다.

    {
      "MyMiddlewareOptionsSection": {
        "Param1": "Param1Value",
        "Param2": "Param2Value"
      }
    }
    

    여기서 MyMiddlewareOptionsSection은 섹션 이름입니다. 옵션 클래스의 이름과 같을 필요는 없습니다.

  3. 옵션 값을 options 클래스와 연결

    옵션 패턴은 ASP.NET Core의 종속성 주입 프레임워크를 사용하여 옵션 형식(예: MyMiddlewareOptions )을 MyMiddlewareOptions 실제 옵션이 있는 개체와 연결합니다.

    Startup클래스를 업데이트합니다.

    1. 를 사용하는 경우 appsettings.json 생성자의 구성 작성기 에 추가합니다. Startup

      public Startup(IHostingEnvironment env)
      {
          var builder = new ConfigurationBuilder()
              .SetBasePath(env.ContentRootPath)
              .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
              .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
              .AddEnvironmentVariables();
          Configuration = builder.Build();
      }
      
    2. 옵션 서비스를 구성합니다.

      public void ConfigureServices(IServiceCollection services)
      {
          // Setup options service
          services.AddOptions();
      
          // Load options from section "MyMiddlewareOptionsSection"
          services.Configure<MyMiddlewareOptions>(
              Configuration.GetSection("MyMiddlewareOptionsSection"));
      
          // Add framework services.
          services.AddMvc();
      }
      
    3. 옵션을 옵션 클래스와 연결합니다.

      public void ConfigureServices(IServiceCollection services)
      {
          // Setup options service
          services.AddOptions();
      
          // Load options from section "MyMiddlewareOptionsSection"
          services.Configure<MyMiddlewareOptions>(
              Configuration.GetSection("MyMiddlewareOptionsSection"));
      
          // Add framework services.
          services.AddMvc();
      }
      
  4. 미들웨어 생성자에 옵션을 삽입합니다. 이는 컨트롤러에 옵션을 삽입 하는 것과 유사 합니다.

    public class MyMiddlewareWithParams
    {
        private readonly RequestDelegate _next;
        private readonly MyMiddlewareOptions _myMiddlewareOptions;
    
        public MyMiddlewareWithParams(RequestDelegate next,
            IOptions<MyMiddlewareOptions> optionsAccessor)
        {
            _next = next;
            _myMiddlewareOptions = optionsAccessor.Value;
        }
    
        public async Task Invoke(HttpContext context)
        {
            // Do something with context near the beginning of request processing
            // using configuration in _myMiddlewareOptions
    
            await _next.Invoke(context);
    
            // Do something with context near the end of request processing
            // using configuration in _myMiddlewareOptions
        }
    }
    

    에 미들웨어를 추가 하는 Usemiddleware 확장 메서드는 IApplicationBuilder 종속성 주입을 담당 합니다.

    이는 개체로 제한 되지 않습니다 IOptions . 미들웨어에 필요한 다른 모든 개체를 이러한 방식으로 삽입할 수 있습니다.

직접 주입을 통해 미들웨어 옵션 로드

옵션 패턴에는 옵션 값과 소비자 간의 느슨한 결합을 만드는 이점이 있습니다. 옵션 클래스를 실제 옵션 값과 연결한 후에는 다른 모든 클래스가 종속성 주입 프레임 워크를 통해 옵션에 대 한 액세스 권한을 얻을 수 있습니다. 옵션 값 주위에 전달할 필요가 없습니다.

이는 다른 옵션을 사용 하 여 동일한 미들웨어를 두 번 사용 하려는 경우에도 중단 됩니다. 예를 들어 서로 다른 역할을 허용 하는 여러 분기에서 사용 되는 권한 부여 미들웨어가 있습니다. 두 가지 옵션 개체를 하나의 옵션 클래스에 연결할 수 없습니다.

이 솔루션은 클래스의 실제 옵션 값을 사용 하 여 옵션 개체를 가져온 Startup 다음 미들웨어의 각 인스턴스에 직접 전달 하는 것입니다.

  1. 두 번째 키를에 추가 합니다. appsettings.json

    파일에 두 번째 옵션 집합을 추가 하려면 새 키를 사용 하 여 해당 옵션을 고유 하 게 appsettings.json 식별 합니다.

    {
      "MyMiddlewareOptionsSection2": {
        "Param1": "Param1Value2",
        "Param2": "Param2Value2"
      },
      "MyMiddlewareOptionsSection": {
        "Param1": "Param1Value",
        "Param2": "Param2Value"
      }
    }
    
  2. 옵션 값을 검색 하 여 미들웨어에 전달 합니다. Use...파이프라인에 미들웨어를 추가 하는 확장 메서드는 옵션 값에 전달할 논리적인 위치입니다.

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();
    
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }
    
        app.UseMyMiddleware();
    
        app.UseMyMiddlewareWithParams();
    
        var myMiddlewareOptions = Configuration.GetSection("MyMiddlewareOptionsSection").Get<MyMiddlewareOptions>();
        var myMiddlewareOptions2 = Configuration.GetSection("MyMiddlewareOptionsSection2").Get<MyMiddlewareOptions>();
        app.UseMyMiddlewareWithParams(myMiddlewareOptions);
        app.UseMyMiddlewareWithParams(myMiddlewareOptions2);
    
        app.UseMyTerminatingMiddleware();
    
        // Create branch to the MyHandlerMiddleware. 
        // All requests ending in .report will follow this branch.
        app.MapWhen(
            context => context.Request.Path.ToString().EndsWith(".report"),
            appBranch => {
                // ... optionally add more middleware to this branch
                appBranch.UseMyHandler();
            });
    
        app.MapWhen(
            context => context.Request.Path.ToString().EndsWith(".context"),
            appBranch => {
                appBranch.UseHttpContextDemoMiddleware();
            });
    
        app.UseStaticFiles();
    
        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
    
  3. 미들웨어가 options 매개 변수를 사용할 수 있도록 합니다. Use...옵션 매개 변수를 사용 하 여에 전달 하는 확장 메서드의 오버 로드를 제공 UseMiddleware 합니다. UseMiddleware매개 변수를 사용 하 여를 호출 하면 미들웨어 개체를 인스턴스화할 때 미들웨어 생성자에 매개 변수를 전달 합니다.

    public static class MyMiddlewareWithParamsExtensions
    {
        public static IApplicationBuilder UseMyMiddlewareWithParams(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<MyMiddlewareWithParams>();
        }
    
        public static IApplicationBuilder UseMyMiddlewareWithParams(
            this IApplicationBuilder builder, MyMiddlewareOptions myMiddlewareOptions)
        {
            return builder.UseMiddleware<MyMiddlewareWithParams>(
                new OptionsWrapper<MyMiddlewareOptions>(myMiddlewareOptions));
        }
    }
    

    개체의 옵션 개체를 래핑하는 방법을 확인 OptionsWrapper 합니다. 이렇게 하면 IOptions 미들웨어 생성자가 예상한 대로 를 구현합니다.

새 HttpContext로 마이그레이션

앞에서 Invoke 미들웨어의 메서드가 형식의 매개 변수를 사용하는 것을 보았습니다. HttpContext

public async Task Invoke(HttpContext context)

HttpContext 는 ASP.NET Core에서 크게 변경되었습니다. 이 섹션에서는 System.Web.HttpContext의 가장 일반적으로 사용되는 속성을 새 로 변환하는 방법을 Microsoft.AspNetCore.Http.HttpContext 보여줍니다.

HttpContext

HttpContext.Items는 다음으로 변환됩니다.

IDictionary<object, object> items = httpContext.Items;

고유한 요청 ID(해당 System.Web.HttpContext 없음)

각 요청에 대한 고유 ID를 제공합니다. 로그에 를 포함하는 것이 매우 유용합니다.

string requestId = httpContext.TraceIdentifier;

HttpContext.Request

HttpContext.Request.HttpMethod는 다음으로 변환됩니다.

string httpMethod = httpContext.Request.Method;

HttpContext.Request.QueryString은 다음으로 변환됩니다.

IQueryCollection queryParameters = httpContext.Request.Query;

// If no query parameter "key" used, values will have 0 items
// If single value used for a key (...?key=v1), values will have 1 item ("v1")
// If key has multiple values (...?key=v1&key=v2), values will have 2 items ("v1" and "v2")
IList<string> values = queryParameters["key"];

// If no query parameter "key" used, value will be ""
// If single value used for a key (...?key=v1), value will be "v1"
// If key has multiple values (...?key=v1&key=v2), value will be "v1,v2"
string value = queryParameters["key"].ToString();

HttpContext.Request.UrlHttpContext.Request.RawUrl은 다음으로 변환합니다.

// using Microsoft.AspNetCore.Http.Extensions;
var url = httpContext.Request.GetDisplayUrl();

HttpContext.Request.IsSecureConnection은 다음으로 변환됩니다.

var isSecureConnection = httpContext.Request.IsHttps;

HttpContext.Request.UserHostAddress는 다음으로 변환됩니다.

var userHostAddress = httpContext.Connection.RemoteIpAddress?.ToString();

HttpContext.Request. Cookie s는 다음으로 변환됩니다.

IRequestCookieCollection cookies = httpContext.Request.Cookies;
string unknownCookieValue = cookies["unknownCookie"]; // will be null (no exception)
string knownCookieValue = cookies["cookie1name"];     // will be actual value

HttpContext.Request.RequestContext.RouteData는 다음으로 변환됩니다.

var routeValue = httpContext.GetRouteValue("key");

HttpContext.Request.Headers는 다음으로 변환됩니다.

// using Microsoft.AspNetCore.Http.Headers;
// using Microsoft.Net.Http.Headers;

IHeaderDictionary headersDictionary = httpContext.Request.Headers;

// GetTypedHeaders extension method provides strongly typed access to many headers
var requestHeaders = httpContext.Request.GetTypedHeaders();
CacheControlHeaderValue cacheControlHeaderValue = requestHeaders.CacheControl;

// For unknown header, unknownheaderValues has zero items and unknownheaderValue is ""
IList<string> unknownheaderValues = headersDictionary["unknownheader"];
string unknownheaderValue = headersDictionary["unknownheader"].ToString();

// For known header, knownheaderValues has 1 item and knownheaderValue is the value
IList<string> knownheaderValues = headersDictionary[HeaderNames.AcceptLanguage];
string knownheaderValue = headersDictionary[HeaderNames.AcceptLanguage].ToString();

HttpContext.Request.UserAgent는 다음으로 변환됩니다.

string userAgent = headersDictionary[HeaderNames.UserAgent].ToString();

HttpContext 참조 페이지는 다음으로 변환 됩니다.

string urlReferrer = headersDictionary[HeaderNames.Referer].ToString();

HttpContext. ContentType 은 다음과 같이 변환 합니다.

// using Microsoft.Net.Http.Headers;

MediaTypeHeaderValue mediaHeaderValue = requestHeaders.ContentType;
string contentType = mediaHeaderValue?.MediaType.ToString();   // ex. application/x-www-form-urlencoded
string contentMainType = mediaHeaderValue?.Type.ToString();    // ex. application
string contentSubType = mediaHeaderValue?.SubType.ToString();  // ex. x-www-form-urlencoded

System.Text.Encoding requestEncoding = mediaHeaderValue?.Encoding;

HttpContext. Form 은 다음과 같이 변환 됩니다.

if (httpContext.Request.HasFormContentType)
{
    IFormCollection form;

    form = httpContext.Request.Form; // sync
    // Or
    form = await httpContext.Request.ReadFormAsync(); // async

    string firstName = form["firstname"];
    string lastName = form["lastname"];
}

경고

콘텐츠 하위 형식이 x-www-form-urlencoded 또는 양식 데이터 인 경우에만 양식 값을 읽습니다.

InputStream 는 다음과 같이 변환 됩니다.

string inputBody;
using (var reader = new System.IO.StreamReader(
    httpContext.Request.Body, System.Text.Encoding.UTF8))
{
    inputBody = reader.ReadToEnd();
}

경고

이 코드는 파이프라인의 끝에 있는 처리기 형식 미들웨어 에서만 사용 합니다.

위에서 설명한 대로 요청 당 한 번만 원시 본문을 읽을 수 있습니다. 첫 번째 읽은 후 본문을 읽으려고 시도 하는 미들웨어는 빈 본문을 읽습니다.

이는 버퍼에서 수행 되기 때문에 이전에 표시 된 대로 폼을 읽는 경우에는 적용 되지 않습니다.

HttpContext 응답

Httpcontext. Statushttpcontext 설명 으로 변환 합니다.

// using Microsoft.AspNetCore.Http;
httpContext.Response.StatusCode = StatusCodes.Status200OK;

Httpcontext. ContentEncoding 및 Httpcontext. ContentType 은 다음으로 변환 합니다.

// using Microsoft.Net.Http.Headers;
var mediaType = new MediaTypeHeaderValue("application/json");
mediaType.Encoding = System.Text.Encoding.UTF8;
httpContext.Response.ContentType = mediaType.ToString();

또한 직접 Httpcontext.current에 대 한 ContentType 은 다음과 같이 변환 됩니다.

httpContext.Response.ContentType = "text/html";

HttpContext. 출력 은 다음과 같이 변환 됩니다.

string responseContent = GetResponseContent();
await httpContext.Response.WriteAsync(responseContent);

TransmitFile

에서 파일을 처리 하는 방법을 설명 ASP.NET Core의 요청 기능 합니다.

HttpContext. 헤더

응답 본문에 쓴 후에 응답 헤더를 설정 하는 경우 응답 헤더를 보내는 것은 복잡 하므로 전송 되지 않습니다.

해결 방법은 응답에 쓰기를 시작 하기 직전에 호출 되는 콜백 메서드를 설정 하는 것입니다. 미들웨어에서 메서드를 시작할 때이 작업을 수행 하는 것이 가장 좋습니다 Invoke . 응답 헤더를 설정하는 것은 이 콜백 메서드입니다.

다음 코드는 라는 콜백 메서드를 SetHeaders 설정합니다.

public async Task Invoke(HttpContext httpContext)
{
    // ...
    httpContext.Response.OnStarting(SetHeaders, state: httpContext);

SetHeaders콜백 메서드는 다음과 같습니다.

// using Microsoft.AspNet.Http.Headers;
// using Microsoft.Net.Http.Headers;

private Task SetHeaders(object context)
{
    var httpContext = (HttpContext)context;

    // Set header with single value
    httpContext.Response.Headers["ResponseHeaderName"] = "headerValue";

    // Set header with multiple values
    string[] responseHeaderValues = new string[] { "headerValue1", "headerValue1" };
    httpContext.Response.Headers["ResponseHeaderName"] = responseHeaderValues;

    // Translating ASP.NET 4's HttpContext.Response.RedirectLocation  
    httpContext.Response.Headers[HeaderNames.Location] = "http://www.example.com";
    // Or
    httpContext.Response.Redirect("http://www.example.com");

    // GetTypedHeaders extension method provides strongly typed access to many headers
    var responseHeaders = httpContext.Response.GetTypedHeaders();

    // Translating ASP.NET 4's HttpContext.Response.CacheControl 
    responseHeaders.CacheControl = new CacheControlHeaderValue
    {
        MaxAge = new System.TimeSpan(365, 0, 0, 0)
        // Many more properties available 
    };

    // If you use .NET Framework 4.6+, Task.CompletedTask will be a bit faster
    return Task.FromResult(0);
}

HttpContext.Response. Cookie s

Cookie는 Set- Cookie 응답 헤더에서 브라우저로 이동합니다. 따라서 cookie 을 보내려면 응답 헤더를 보내는 데 사용되는 것과 동일한 콜백이 필요합니다.

public async Task Invoke(HttpContext httpContext)
{
    // ...
    httpContext.Response.OnStarting(SetCookies, state: httpContext);
    httpContext.Response.OnStarting(SetHeaders, state: httpContext);

SetCookies콜백 메서드는 다음과 같습니다.

private Task SetCookies(object context)
{
    var httpContext = (HttpContext)context;

    IResponseCookies responseCookies = httpContext.Response.Cookies;

    responseCookies.Append("cookie1name", "cookie1value");
    responseCookies.Append("cookie2name", "cookie2value",
        new CookieOptions { Expires = System.DateTime.Now.AddDays(5), HttpOnly = true });

    // If you use .NET Framework 4.6+, Task.CompletedTask will be a bit faster
    return Task.FromResult(0); 
}

추가 리소스