Открыть текущий объект HttpContext в ASP.NET основной
мне нужно получить доступ к текущему HttpContext
в статическом методе или служебной службе.
С классикой ASP.NET MVC и System.Web
, Я бы просто использовать HttpContext.Current
для статического доступа к контексту. Но как мне это сделать в ASP.NET ядро?
4 ответа:
HttpContext.Current
больше не существует в ASP.NET ядро, но есть новый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 framework),но он работает:на
public class Startup
добавить свойство
public IConfigurationRoot Configuration { get; }
а затем добавить синглтон IHttpContextAccessor для DI в ConfigureServices.
// 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>();
затем в Configure
public void Configure( IApplicationBuilder app ,IHostingEnvironment env ,ILoggerFactory loggerFactory ) {
добавить параметр DI
IServiceProvider svp
, поэтому метод выглядит так:public void Configure( IApplicationBuilder app ,IHostingEnvironment env ,ILoggerFactory loggerFactory ,IServiceProvider svp) {
затем создайте класс замены для System.Веб-сайт:
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
, сохраните этого поставщика услуг в статической переменной "ServiceProvider" в только что созданной фиктивной системе классов.Сеть.HttpContext (Система.Сеть.HttpContext.Поставщику услуги)и установите HostingEnvironment.Размещение в true
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
это по сути системы.Веб сделал, только что вы никогда не видели его (я думаю, переменная была объявлена как внутренняя, а не публичная).
// 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 веб-формы, вы получите NullReference, когда вы пытаетесь получить доступ к HttpContext, когда его нет, например, как это было в
Application_Start
в глобальном.асакс.я подчеркиваю опять же, это работает только если вы на самом деле добавил
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
как я и писал, Вы должны.
Добро пожаловать в шаблон ServiceLocator в шаблоне DI;)
Чтобы узнать о рисках и побочных эффектах, обратитесь к врачу-резиденту или фармацевту - или изучите источники .NET Core по адресу github.com/aspnet, и сделать некоторые испытания.
возможно, более поддерживаемый метод будет добавлять этот вспомогательный класс
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; } } } }
а потом звонит HttpContext.Настройка при запуске- > настроить
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>() );
просто добавить к другим ответам...
In ASP.NET ядро 2.1, есть the
AddHttpContextAccessor
метод расширения, что будет регистрироватьIHttpContxtAccessor
с правильной жизни.
наиболее законным способом, который я придумал, было введение IHttpContextAccessor в вашу статическую реализацию следующим образом:
public static class HttpHelper { private static IHttpContextAccessor _accessor; public static void Configure(IHttpContextAccessor httpContextAccessor) { _accessor = httpContextAccessor; } public static HttpContext HttpContext => _accessor.HttpContext; }
затем назначение IHttpContextAccessor в Startup Configure должно выполнить эту работу.
HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
Я думаю, вам также нужно зарегистрировать сервис singleton:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();