[C#] ASP.NET Core에서 현재 HttpContext에 액세스

현재에 액세스해야합니다 HttpContext정적 메소드 또는 유틸리티 서비스에서 에 .

고전적인 ASP.NET MVC 및 을 사용하면 컨텍스트에 정적으로 액세스하는 데 System.Web사용 HttpContext.Current합니다. 그러나 ASP.NET Core에서 어떻게해야합니까?



답변

HttpContext.CurrentASP.NET Core에는 더 이상 존재하지 않지만 IHttpContextAccessor종속성을 주입하고 현재를 검색하는 데 사용할 수 있는 새로운 기능 이 있습니다 HttpContext.

public class MyComponent : IMyComponent
{
    private readonly IHttpContextAccessor _contextAccessor;

    public MyComponent(IHttpContextAccessor contextAccessor)
    {
        _contextAccessor = contextAccessor;
    }

    public string GetDataFromSession()
    {
        return _contextAccessor.HttpContext.Session.GetString(*KEY*);
    }
}


답변

괴롭힘.
그렇습니다 당신은
큰 이주하는 사람들을위한 비밀 팁정크코드 덩어리 (한숨, 프로 이디 언 전표).
다음 방법은 사탄의 표현 작업을 적극적으로 수행하는 .NET Core 프레임 워크 개발자의 눈에 띄는 해킹의 악의적 인 수단 이지만 작동합니다 .

public class Startup

속성을 추가

public IConfigurationRoot Configuration { get; }

그런 다음 ConfigureServices에서 DI에 싱글 톤 IHttpContextAccessor를 추가하십시오.

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();

그런 다음 구성에서

    public void Configure(
              IApplicationBuilder app
             ,IHostingEnvironment env
             ,ILoggerFactory loggerFactory
    )
    {

DI Parameter를 추가하면 IServiceProvider svp메소드는 다음과 같습니다.

    public void Configure(
           IApplicationBuilder app
          ,IHostingEnvironment env
          ,ILoggerFactory loggerFactory
          ,IServiceProvider svp)
    {

다음으로 System.Web의 대체 클래스를 만듭니다.

namespace System.Web
{

    namespace Hosting
    {
        public static class HostingEnvironment
        {
            public static bool m_IsHosted;

            static HostingEnvironment()
            {
                m_IsHosted = false;
            }

            public static bool IsHosted
            {
                get
                {
                    return m_IsHosted;
                }
            }
        }
    }


    public static class HttpContext
    {
        public static IServiceProvider ServiceProvider;

        static HttpContext()
        { }


        public static Microsoft.AspNetCore.Http.HttpContext Current
        {
            get
            {
                // var factory2 = ServiceProvider.GetService<Microsoft.AspNetCore.Http.IHttpContextAccessor>();
                object factory = ServiceProvider.GetService(typeof(Microsoft.AspNetCore.Http.IHttpContextAccessor));

                // Microsoft.AspNetCore.Http.HttpContextAccessor fac =(Microsoft.AspNetCore.Http.HttpContextAccessor)factory;
                Microsoft.AspNetCore.Http.HttpContext context = ((Microsoft.AspNetCore.Http.HttpContextAccessor)factory).HttpContext;
                // context.Response.WriteAsync("Test");

                return context;
            }
        }


    } // End Class HttpContext 


}

이제,를 추가 한 Configure IServiceProvider svp에서이 서비스 제공자를 방금 작성된 더미 클래스 System.Web.HttpContext (System.Web.HttpContext.ServiceProvider)의 정적 변수 “ServiceProvider”에 저장하십시오.

HostingEnvironment.IsHosted를 true로 설정하십시오.

System.Web.Hosting.HostingEnvironment.m_IsHosted = true;

이것은 본질적으로 System.Web이 한 일입니다. 단지 보지 못했습니다 (변수가 public 대신 내부로 선언 된 것 같습니다).

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider svp)
{
    loggerFactory.AddConsole(Configuration.GetSection("Logging"));
    loggerFactory.AddDebug();

    ServiceProvider = svp;
    System.Web.HttpContext.ServiceProvider = svp;
    System.Web.Hosting.HostingEnvironment.m_IsHosted = true;


    app.UseCookieAuthentication(new CookieAuthenticationOptions()
    {
        AuthenticationScheme = "MyCookieMiddlewareInstance",
        LoginPath = new Microsoft.AspNetCore.Http.PathString("/Account/Unauthorized/"),
        AccessDeniedPath = new Microsoft.AspNetCore.Http.PathString("/Account/Forbidden/"),
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        CookieSecure = Microsoft.AspNetCore.Http.CookieSecurePolicy.SameAsRequest

       , CookieHttpOnly=false

    });

ASP.NET Web-Forms에서와 같이 Application_Startglobal.asax 와 같이 HttpContext가 없을 때 HttpContext에 액세스하려고하면 NullReference가 발생합니다 .

다시 강조합니다. 실제로 추가 한 경우에만 작동합니다

services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();

내가 쓴 것처럼
DI 패턴 내 ServiceLocator 패턴에 오신 것을 환영합니다.)
위험과 부작용에 대해서는 거주 의사 나 약사에게 문의하거나 github.com/aspnet 에서 .NET Core의 소스를 연구하고 몇 가지 테스트를 수행하십시오.


아마도 더 관리 가능한 방법은이 도우미 클래스를 추가하는 것입니다

namespace System.Web
{

    public static class HttpContext
    {
        private static Microsoft.AspNetCore.Http.IHttpContextAccessor m_httpContextAccessor;


        public static void Configure(Microsoft.AspNetCore.Http.IHttpContextAccessor httpContextAccessor)
        {
            m_httpContextAccessor = httpContextAccessor;
        }


        public static Microsoft.AspNetCore.Http.HttpContext Current
        {
            get
            {
                return m_httpContextAccessor.HttpContext;
            }
        }


    }


}

그런 다음 Startup-> Configure에서 HttpContext.Configure를 호출하십시오.

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


    System.Web.HttpContext.Configure(app.ApplicationServices.
        GetRequiredService<Microsoft.AspNetCore.Http.IHttpContextAccessor>()
    );


답변

다른 답변에 추가하려면 …

ASP.NET 코어 2.1, 거기에 확장 방법은 그이 등록됩니다, 정확한 수명과 :AddHttpContextAccessorIHttpContextAccessor

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();

    // Other code...
}


답변

내가 만든 가장 합법적 인 방법은 다음과 같이 정적 구현에 IHttpContextAccessor를 주입하는 것입니다.

public static class HttpHelper
{
     private static IHttpContextAccessor _accessor;
     public static void Configure(IHttpContextAccessor httpContextAccessor)
     {
          _accessor = httpContextAccessor;
     }

     public static HttpContext HttpContext => _accessor.HttpContext;
}

그런 다음 시작 구성에서 IHttpContextAccessor를 지정하면 작업이 수행됩니다.

HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());

서비스 싱글 톤도 등록해야한다고 생각합니다.

services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();


답변

이 기사에 따르면 ASP.NET Core의 프레임 워크 구성 요소 외부에서 HttpContext에 액세스

namespace System.Web
{
    public static class HttpContext
    {
        private static IHttpContextAccessor _contextAccessor;

        public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext;

        internal static void Configure(IHttpContextAccessor contextAccessor)
        {
            _contextAccessor = contextAccessor;
        }
    }
}

그때:

public static class StaticHttpContextExtensions
{
    public static void AddHttpContextAccessor(this IServiceCollection services)
    {
        services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    }

    public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
    {
        var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
        System.Web.HttpContext.Configure(httpContextAccessor);
        return app;
    }
}

그때:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddHttpContextAccessor();
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseStaticHttpContext();
        app.UseMvc();
    }
}

다음과 같이 사용할 수 있습니다.

using System.Web;

public class MyService
{
   public void DoWork()
   {
    var context = HttpContext.Current;
    // continue with context instance
   }
}


답변

시작시

services.AddHttpContextAccessor();

컨트롤러에서

public class HomeController : Controller
    {
        private readonly IHttpContextAccessor _context;

        public HomeController(IHttpContextAccessor context)
        {
            _context = context;
        }
        public IActionResult Index()
        {
           var context = _context.HttpContext.Request.Headers.ToList();
           return View();
        }
   }


답변