HaB*_*aBo 182 c# .net-core asp.net-core
我们目前正在使用ASP.NET Core重写/转换我们的ASP.NET WebForms应用程序.尽量避免重新设计.
我们HttpContext在类库中使用了一个部分来检查当前状态.如何HttpContext.Current在.NET Core 1.0中访问?
var current = HttpContext.Current;
if (current == null)
{
// do something here
// string connection = Configuration.GetConnectionString("MyDb");
}
Run Code Online (Sandbox Code Playgroud)
我需要访问它才能构建当前的应用程序主机.
$"{current.Request.Url.Scheme}://{current.Request.Url.Host}{(current.Request.Url.Port == 80 ? "" : ":" + current.Request.Url.Port)}";
Run Code Online (Sandbox Code Playgroud)
Nat*_*ini 231
作为一般规则,将Web窗体或MVC5应用程序转换为ASP.NET Core 将需要大量的重构.
HttpContext.Current已在ASP.NET Core中删除.从单独的类库访问当前HTTP上下文是ASP.NET Core试图避免的混乱体系结构的类型.有几种方法可以在ASP.NET Core中重新构建它.
您可以通过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
}
Run Code Online (Sandbox Code Playgroud)
如果您正在为ASP.NET Core管道编写自定义中间件,则当前请求HttpContext将Invoke自动传递到您的方法中:
public Task Invoke(HttpContext context)
{
// Do something with the current HTTP context...
}
Run Code Online (Sandbox Code Playgroud)
最后,您可以使用IHttpContextAccessor帮助程序服务来获取由ASP.NET Core依赖注入系统管理的任何类中的HTTP上下文.当您拥有控制器使用的公共服务时,这非常有用.
在构造函数中请求此接口:
public MyMiddleware(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以以安全的方式访问当前的HTTP上下文:
var context = _httpContextAccessor.HttpContext;
// Do something with the current HTTP context...
Run Code Online (Sandbox Code Playgroud)
IHttpContextAccessor默认情况下并不总是添加到服务容器中,因此请将其注册ConfigureServices为安全:
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
// if < .NET Core 2.2 use this
//services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
// Other code...
}
Run Code Online (Sandbox Code Playgroud)
Ste*_*ger 48
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)
HLS*_*HLS 10
如果您确实需要对当前上下文的静态访问,则可以使用此解决方案.在Startup.Configure(...)中
app.Use(async (httpContext, next) =>
{
CallContext.LogicalSetData("CurrentContextKey", httpContext);
try
{
await next();
}
finally
{
CallContext.FreeNamedDataSlot("CurrentContextKey");
}
});
Run Code Online (Sandbox Code Playgroud)
当你需要它时,你可以得到它:
HttpContext context = CallContext.LogicalGetData("CurrentContextKey") as HttpContext;
Run Code Online (Sandbox Code Playgroud)
我希望有所帮助.请记住,当您无法选择时,此解决方法.最佳实践是使用de依赖注入.
| 归档时间: |
|
| 查看次数: |
186015 次 |
| 最近记录: |