답변:
HttpContext.Current
ASP.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*);
}
}
CallContextServiceLocator
으로는 DI를 주입하지 않은 인스턴스에서도 서비스를 해결하는 데 사용할 수 있습니다 CallContextServiceLocator.Locator.ServiceProvider.GetService<IHttpContextAccessor>()
. 실제로, 당신이 그것을 피할 수 있다면 그것은 큰 일입니다 :)
괴롭힘.
그렇습니다 당신은
큰 이주하는 사람들을위한 비밀 팁정크코드 덩어리 (한숨, 프로 이디 언 전표).
다음 방법은 사탄의 표현 작업을 적극적으로 수행하는 .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_Start
global.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, 거기에 확장 방법은 그이 등록됩니다, 정확한 수명과 :AddHttpContextAccessor
IHttpContextAccessor
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();
}
}
IHttpContextAccessor
DI 컨테이너가 인스턴스를 해결하는 장소에서만 사용할 수 있다는 점도 언급 할 가치 가 있습니다.