Saltar al contenido

¿Cómo obtener HttpContext.Current en ASP.NET Core?

Sé libre de compartir nuestra página y códigos con otro, necesitamos tu ayuda para aumentar nuestra comunidad.

Solución:

Como regla general, convertir una aplicación Web Forms o MVC5 a ASP.NET Core requerirá una cantidad significativa de refactorización.

HttpContext.Current se eliminó en ASP.NET Core. Acceder al contexto HTTP actual desde una biblioteca de clases separada es el tipo de arquitectura desordenada que ASP.NET Core intenta evitar. Hay algunas formas de rediseñar esto en ASP.NET Core.

Propiedad HttpContext

Puede acceder al contexto HTTP actual a través del HttpContext propiedad en cualquier controlador. Lo más parecido a su muestra de código original sería pasar HttpContext en el método que está llamando:

public class HomeController : Controller

    public IActionResult Index()
    
        MyMethod(HttpContext);

        // Other code
    


public void MyMethod(Microsoft.AspNetCore.Http.HttpContext context)

    var host = $"context.Request.Scheme://context.Request.Host";

    // Other code

Parámetro HttpContext en middleware

Si está escribiendo middleware personalizado para la canalización de ASP.NET Core, la solicitud actual HttpContext se pasa a tu Invoke método automáticamente:

public Task Invoke(HttpContext context)

    // Do something with the current HTTP context...

Accesor de contexto HTTP

Finalmente, puede usar el IHttpContextAccessor servicio auxiliar para obtener el contexto HTTP en cualquier clase administrada por el sistema de inyección de dependencias ASP.NET Core. Esto es útil cuando tiene un servicio común que utilizan sus controladores.

Solicite esta interfaz en su constructor:

public MyMiddleware(IHttpContextAccessor httpContextAccessor)

    _httpContextAccessor = httpContextAccessor;

Luego puede acceder al contexto HTTP actual de una manera segura:

var context = _httpContextAccessor.HttpContext;
// Do something with the current HTTP context...

IHttpContextAccessor no siempre se agrega al contenedor de servicios de forma predeterminada, así que regístrelo en ConfigureServices Solo para estar seguros:

public void ConfigureServices(IServiceCollection services)

    services.AddHttpContextAccessor();
    // if < .NET Core 2.2 use this
    //services.TryAddSingleton();

    // Other code...

Nigromante.
SÍ PUEDES, y así es como.
Un consejo secreto para quienes migran a gran escala chatarra trozos de código:

El siguiente método es un carbunclo malvado de un truco que se dedica activamente a llevar a cabo el trabajo expreso de satanás (a los ojos de los desarrolladores de .NET Core framework), pero funciona:

En public class Startup

agregar una propiedad

public IConfigurationRoot Configuration  get; 

Y luego agregue un singleton IHttpContextAccessor a DI en ConfigureServices.

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton();

Luego en Configurar

    public void Configure(
              IApplicationBuilder app
             ,IHostingEnvironment env
             ,ILoggerFactory loggerFactory
    )
    {

agregar el parámetro DI IServiceProvider svp, por lo que el método se ve así:

    public void Configure(
           IApplicationBuilder app
          ,IHostingEnvironment env
          ,ILoggerFactory loggerFactory
          ,IServiceProvider svp)
    {

A continuación, cree una clase de reemplazo para 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();
                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 



Ahora en Configurar, donde agregó el IServiceProvider svp, guarde este proveedor de servicios en el static variable “ServiceProvider” en la clase ficticia System.Web.HttpContext (System.Web.HttpContext.ServiceProvider) recién creada

y establezca HostingEnvironment.IsHosted en true

System.Web.Hosting.HostingEnvironment.m_IsHosted = true;

esto es esencialmente lo que hizo System.Web, solo que nunca lo vio (supongo que la variable se declaró como interna en lugar de pública).

// 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

    );

Al igual que en ASP.NET Web-Forms, obtendrá una NullReference cuando intente acceder a un HttpContext cuando no hay ninguno, como solía estar en Application_Start en global.asax.

Insisto de nuevo, esto solo funciona si realmente agregaste

services.AddSingleton();

como te escribí deberías.
Bienvenido al patrón ServiceLocator dentro del patrón DI;)
Para conocer los riesgos y los efectos secundarios, consulte con su médico o farmacéutico residente, o estudie las fuentes de .NET Core en github.com/aspnet y realice algunas pruebas.


Quizás un método más fácil de mantener sería agregar esta clase auxiliar

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;
            
        


    



Y luego llamar a HttpContext.Configure en Inicio-> Configurar

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()
    );

Hay una solución para esto si realmente necesita un static acceso al contexto actual. En Startup.Configure (….)

app.Use(async (httpContext, next) =>

    CallContext.LogicalSetData("CurrentContextKey", httpContext);
    try
    
        await next();
    
    finally
    
        CallContext.FreeNamedDataSlot("CurrentContextKey");
    
);

Y cuando lo necesite, puede obtenerlo con:

HttpContext context = CallContext.LogicalGetData("CurrentContextKey") as HttpContext;

Espero que eso ayude. Tenga en cuenta que esta solución es cuando no tiene otra opción. La mejor práctica es utilizar la inyección de dependencia.

Si estás de acuerdo, tienes el poder dejar un post acerca de qué le añadirías a esta reseña.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *