Necromancing.
ДА МОЖНО
Секретный совет для тех, кто мигрируетджонкикуски (вздох, оговорка по Фрейду) кода.
Следующий метод является злым карбункулом хака, который активно выполняет экспресс-работу сатаны (в глазах разработчиков .NET Core), но он работает :
В 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.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
, сохраните этого поставщика услуг в статической переменной «ServiceProvider» в только что созданном фиктивном классе System.Web.HttpContext (System.Web.HttpContext.ServiceProvider)
и установите для HostingEnvironment.IsHosted значение true
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
По сути, это то, что сделал System.Web, только вы никогда этого не видели (я предполагаю, что переменная была объявлена как внутренняя, а не общедоступная).
// 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
global.asax.
Еще раз подчеркиваю, это работает, только если вы действительно добавили
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.Configure в Startup-> 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>()
);
IHttpContextAccessor
это будет доступно только в тех местах, где контейнер DI разрешает экземпляр.