Некромантування.
ТАК, ТИ МОЖЕШ
Секретну пораду для великих мігрантівджонкишматки (зітхання, фрейдівське ковзання) коду.
Наступний метод - злий карбункул хака, який активно бере участь у експрес-роботі сатани (в очах розробників .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>();
Потім у Налаштувати
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
}
Тепер у налаштуваннях, де ви додали IServiceProvider svp
, збережіть цього постачальника послуг у статичну змінну "ServiceProvider" у щойно створеному манекені класу System.Web.HttpContext (System.Web.HttpContext.ServiceProvider)
і встановіть HostingEn Environmentment. Підтверджено до істини
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 Web-Forms, ви отримаєте 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 вирішує екземпляр.