max*_*her 113 c# asp.net-core
我需要HttpContext
在静态方法或实用程序服务中访问当前.
使用经典的ASP.NET MVC System.Web
,我只是用来HttpContext.Current
静态访问上下文.但是我如何在ASP.NET Core中执行此操作?
Kév*_*let 129
HttpContext.Current
在ASP.NET Core中不再存在但是有一个新的 IHttpContextAccessor
,你可以在你的依赖项中注入并用于检索当前HttpContext
:
public class MyComponent : IMyComponent
{
private readonly IHttpContextAccessor _contextAccessor;
public MyComponent(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
public string GetDataFromSession()
{
return _contextAccessor.HttpContext.Session.GetString(*KEY*);
}
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ger 29
Necromancing.
是的,你可以
为那些迁移大的人提供秘密提示帆船大块(叹息,弗洛伊德滑动)的代码.
下面的方法是一个黑客的邪恶痈,积极参与执行撒旦的快速工作(在.NET Core框架开发人员的眼中),但它的工作原理:
在 public class Startup
添加一个属性
public IConfigurationRoot Configuration { get; }
Run Code Online (Sandbox Code Playgroud)
然后在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>();
Run Code Online (Sandbox Code Playgroud)
然后在Configure中
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
)
{
Run Code Online (Sandbox Code Playgroud)
添加DI参数IServiceProvider svp
,方法如下:
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
,IServiceProvider svp)
{
Run Code Online (Sandbox Code Playgroud)
接下来,为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
}
Run Code Online (Sandbox Code Playgroud)
现在在Configure中添加了IServiceProvider svp
,将此服务提供者保存到刚创建的虚拟类System.Web.HttpContext(System.Web.HttpContext.ServiceProvider)中的静态变量"ServiceProvider"中
并将HostingEnvironment.IsHosted设置为true
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
Run Code Online (Sandbox Code Playgroud)
这基本上是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
});
Run Code Online (Sandbox Code Playgroud)
就像在ASP.NET Web-Forms中一样,当你尝试访问HttpContext时,你会得到一个NullReference,例如它曾经Application_Start
在global.asax中.
我再次强调,这只有在您真正添加时才有效
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)
就像我写的那样.
欢迎使用DI模式中的ServiceLocator模式;)
有关风险和副作用,请咨询您的住院医生或药剂师 - 或者在github.com/aspnet上研究.NET Core的来源,并进行一些测试.
也许一个更易于维护的方法是添加这个辅助类
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;
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在Startup-> Configure中调用HttpContext.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>()
);
Run Code Online (Sandbox Code Playgroud)
khe*_*ang 21
只是为了添加其他答案......
在ASP.NET 2.1的核心,还有的AddHttpContextAccessor
扩展方法,将注册IHttpContextAccessor
与正确的寿命.
Jan*_*Jan 14
我提出的最合法的方法是在静态实现中注入IHttpContextAccessor,如下所示:
public static class HttpHelper
{
private static IHttpContextAccessor _accessor;
public static void Configure(IHttpContextAccessor httpContextAccessor)
{
_accessor = httpContextAccessor;
}
public static HttpContext HttpContext => _accessor.HttpContext;
}
Run Code Online (Sandbox Code Playgroud)
然后在启动配置中分配IHttpContextAccessor应该可以完成这项工作.
HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
Run Code Online (Sandbox Code Playgroud)
我想你还应该注册服务单例:
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
Run Code Online (Sandbox Code Playgroud)
根据这篇文章:在 ASP.NET Core 中的框架组件之外访问 HttpContext
namespace System.Web
{
public static class HttpContext
{
private static IHttpContextAccessor _contextAccessor;
public static Microsoft.AspNetCore.Http.HttpContext Current => _contextAccessor.HttpContext;
internal static void Configure(IHttpContextAccessor contextAccessor)
{
_contextAccessor = contextAccessor;
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
public static class StaticHttpContextExtensions
{
public static void AddHttpContextAccessor(this IServiceCollection services)
{
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
}
public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
{
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
System.Web.HttpContext.Configure(httpContextAccessor);
return app;
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticHttpContext();
app.UseMvc();
}
}
Run Code Online (Sandbox Code Playgroud)
你可以这样使用它:
using System.Web;
public class MyService
{
public void DoWork()
{
var context = HttpContext.Current;
// continue with context instance
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在启动
services.AddHttpContextAccessor();
Run Code Online (Sandbox Code Playgroud)
在控制器中
public class HomeController : Controller
{
private readonly IHttpContextAccessor _context;
public HomeController(IHttpContextAccessor context)
{
_context = context;
}
public IActionResult Index()
{
var context = _context.HttpContext.Request.Headers.ToList();
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
44091 次 |
最近记录: |