Necromancing.
SÌ PUOI Consiglio
segreto per coloro che migrano in grandegiunchepezzi (sospiro, scivolo freudiano) di codice.
Il seguente metodo è un brutto carbonchio di un hack che è attivamente impegnato nello svolgimento del lavoro espresso di satana (agli occhi degli sviluppatori del framework .NET Core), ma funziona :
Nel public class Startup
aggiungi una proprietà
public IConfigurationRoot Configuration { get; }
E quindi aggiungere un singolo IHttpContextAccessor a DI in 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>();
Quindi in Configura
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
)
{
aggiungi il parametro DI IServiceProvider svp
, quindi il metodo è simile al seguente:
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
,IServiceProvider svp)
{
Quindi, creare una classe di sostituzione per 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
}
Ora in Configura, dove è stato aggiunto IServiceProvider svp
, salvare questo fornitore di servizi nella variabile statica "ServiceProvider" nella classe fittizia appena creata System.Web.HttpContext (System.Web.HttpContext.ServiceProvider)
e imposta HostingEnvironment.IsHosted su true
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
questo è essenzialmente ciò che ha fatto System.Web, solo che non l'hai mai visto (suppongo che la variabile sia stata dichiarata come interna anziché pubblica).
// 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
});
Come nei moduli Web ASP.NET, otterrai un NullReference quando stai tentando di accedere a un HttpContext quando non ce n'è, come in passato era presente Application_Start
in global.asax.
Sottolineo di nuovo, questo funziona solo se hai effettivamente aggiunto
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
come ho scritto dovresti.
Benvenuto nel modello ServiceLocator all'interno del modello DI;)
Per rischi ed effetti collaterali, chiedi al tuo medico o farmacista residente o studia le fonti di .NET Core su github.com/aspnet e fai dei test.
Forse un metodo più mantenibile sarebbe l'aggiunta di questa classe di supporto
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;
}
}
}
}
E quindi chiamare HttpContext.Configure in Avvio-> Configura
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
sarebbe disponibile solo in luoghi in cui il contenitore DI sta risolvendo l'istanza.