C# 如何在ASP.NET核心中获取HttpContext.Current?

C# 如何在ASP.NET核心中获取HttpContext.Current?,c#,asp.net-core,.net-core,C#,Asp.net Core,.net Core,我们目前正在使用ASP.NET核心重写/转换我们的ASP.NET WebForms应用程序。尽量避免重新设计 我们在类库中使用HttpContext检查当前状态。如何访问.NET Core 1.0中的HttpContext.Current var current = HttpContext.Current; if (current == null) { // do something here // string connection = Co

我们目前正在使用ASP.NET核心重写/转换我们的ASP.NET WebForms应用程序。尽量避免重新设计

我们在类库中使用
HttpContext
检查当前状态。如何访问.NET Core 1.0中的
HttpContext.Current

 var current = HttpContext.Current;
     if (current == null)
      {
       // do something here
       // string connection = Configuration.GetConnectionString("MyDb");
      }
我需要访问它才能构建当前的应用程序主机

$"{current.Request.Url.Scheme}://{current.Request.Url.Host}{(current.Request.Url.Port == 80 ? "" : ":" + current.Request.Url.Port)}";

一般来说,将Web表单或MVC5应用程序转换为ASP.NET核心需要进行大量重构

HttpContext.Current
已在ASP.NET核心中删除。从单独的类库访问当前HTTP上下文是ASP.NET Core试图避免的混乱体系结构类型。有几种方法可以在ASP.NET Core中重新构建它

HttpContext属性 您可以通过任何控制器上的
HttpContext
属性访问当前HTTP上下文。与原始代码示例最接近的是将
HttpContext
传递到您正在调用的方法中:

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
}
中间件中的HttpContext参数 如果您正在编写ASP.NET核心管道,则当前请求的
HttpContext
将自动传递到
Invoke
方法中:

public Task Invoke(HttpContext context)
{
    // Do something with the current HTTP context...
}
HTTP上下文访问器 最后,您可以使用
IHttpContextAccessor
helper服务来获取由ASP.NET核心依赖项注入系统管理的任何类中的HTTP上下文。当控制器使用公共服务时,这非常有用

在构造函数中请求此接口:

public MyMiddleware(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}
然后,您可以安全地访问当前HTTP上下文:

var context = _httpContextAccessor.HttpContext;
// Do something with the current HTTP context...
默认情况下,
IHttpContextAccessor
并不总是添加到服务容器中,因此请在
ConfigureServices
中注册它,以确保安全:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    // if < .NET Core 2.2 use this
    //services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    // Other code...
}
public void配置服务(IServiceCollection服务)
{
AddHttpContextAccessor();
//如果<.NET Core 2.2,则使用此
//services.TryAddSingleton();
//其他代码。。。
}

一般来说,将Web表单或MVC5应用程序转换为ASP.NET核心需要进行大量重构

HttpContext.Current
已在ASP.NET核心中删除。从单独的类库访问当前HTTP上下文是ASP.NET Core试图避免的混乱体系结构类型。有几种方法可以在ASP.NET Core中重新构建它

HttpContext属性 您可以通过任何控制器上的
HttpContext
属性访问当前HTTP上下文。与原始代码示例最接近的是将
HttpContext
传递到您正在调用的方法中:

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
}
中间件中的HttpContext参数 如果您正在编写ASP.NET核心管道,则当前请求的
HttpContext
将自动传递到
Invoke
方法中:

public Task Invoke(HttpContext context)
{
    // Do something with the current HTTP context...
}
HTTP上下文访问器 最后,您可以使用
IHttpContextAccessor
helper服务来获取由ASP.NET核心依赖项注入系统管理的任何类中的HTTP上下文。当控制器使用公共服务时,这非常有用

在构造函数中请求此接口:

public MyMiddleware(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}
然后,您可以安全地访问当前HTTP上下文:

var context = _httpContextAccessor.HttpContext;
// Do something with the current HTTP context...
默认情况下,
IHttpContextAccessor
并不总是添加到服务容器中,因此请在
ConfigureServices
中注册它,以确保安全:

public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpContextAccessor();
    // if < .NET Core 2.2 use this
    //services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();

    // Other code...
}
public void配置服务(IServiceCollection服务)
{
AddHttpContextAccessor();
//如果<.NET Core 2.2,则使用此
//services.TryAddSingleton();
//其他代码。。。
}

如果您确实需要对当前上下文进行静态访问,则有一种解决方案。 在Startup.Configure(..)

当您需要时,您可以使用:

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

我希望这有帮助。请记住,这种解决方法是在你没有选择的时候。最佳实践是使用去依赖注入。

如果您确实需要对当前上下文进行静态访问,则有一种解决方案。 在Startup.Configure(..)

当您需要时,您可以使用:

HttpContext context = CallContext.LogicalGetData("CurrentContextKey") as HttpContext;
我希望这有帮助。请记住,这种解决方法是在你没有选择的时候。最佳实践是使用去依赖注入。

坏死术
是的,你可以,这就是为什么
迁移大块代码的秘密提示:
下面的方法是一个黑客的邪恶毒瘤,该黑客正在积极执行撒旦(在.NET核心框架开发人员眼中)的快速工作,但它有效

公共类启动中

添加属性

public IConfigurationRoot Configuration { get; }
然后在ConfigureServices中将单例IHttpContextAccessor添加到DI

    // 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>();
添加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 


}
这基本上就是System.Web所做的,只是您从未见过它(我猜该变量被声明为内部变量而不是公共变量)

与ASP.NET Web表单中一样,当您尝试访问一个HttpContext时,如果没有HttpContext,则会得到一个空引用,例如它以前在global.asax中的
Application\u Start

我再次强调,只有当你真的添加了

services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
然后在启动->配置中调用HttpContext.Configure

    public void Configure(
              IApplicationBuilder app
             ,IHostingEnvironment env
             ,ILoggerFactory loggerFactory
    )
    {
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>()
    );
public void配置(IApplicationBuilder应用程序、IHostingEnvironment环境、iLogger工厂、IServiceProvider svp)
{
loggerFactory.AddConsole(Configuration.GetSection(“Logging”);
loggerFactory.AddDebug();
System.Web.HttpContext.Configure(app.ApplicationServices)。
GetRequiredService()
);
亡灵巫术。
是的,你可以,这就是方法。
迁移大块代码的秘密提示:
下面的方法是一个正在积极从事carryi的黑客的邪恶痈