HttpContext
静的メソッドまたはユーティリティサービスでcurrent にアクセスする必要があります。
従来のASP.NET MVCとではSystem.Web
、HttpContext.Current
静的にコンテキストにアクセスするために使用するだけでした。しかし、ASP.NET Coreでこれを行うにはどうすればよいですか?
HttpContext
静的メソッドまたはユーティリティサービスでcurrent にアクセスする必要があります。
従来のASP.NET MVCとではSystem.Web
、HttpContext.Current
静的にコンテキストにアクセスするために使用するだけでした。しかし、ASP.NET Coreでこれを行うにはどうすればよいですか?
回答:
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*);
}
}
CallContextServiceLocator
DIを使用しないインスタンスからでも、サービスを解決するために使用できますCallContextServiceLocator.Locator.ServiceProvider.GetService<IHttpContextAccessor>()
。あなたはそれを避けることができれば実際には、それは素晴らしいことだ:)
ネクロマンシング。
はい、
大規模に移行する人のための秘訣がらくたコードのチャンク(ため息、フロイトのスリップ)。
次の方法は、悪意のある悪意のある作業を積極的に実行している(.NET Coreフレームワーク開発者の目には当てはまります)、ハックの邪悪なカーバンクルですが、機能します。
に public class Startup
プロパティを追加する
public IConfigurationRoot Configuration { get; }
次に、ConfigureServicesのDIにシングルトンIHttpContextAccessorを追加します。
// 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>();
次に、構成で
public void Configure(
IApplicationBuilder app
,IHostingEnvironment env
,ILoggerFactory loggerFactory
)
{
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
}
次に、を追加したConfigureで、IServiceProvider svp
このサービスプロバイダーを、作成したダミークラスSystem.Web.HttpContext(System.Web.HttpContext.ServiceProvider)の静的変数「ServiceProvider」に保存します。
そしてHostingEnvironment.IsHostedをtrueに設定します
System.Web.Hosting.HostingEnvironment.m_IsHosted = true;
これは基本的に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
});
ASP.NET Webフォームと同様に、global.asaxにあったようなHttpContextがない場合にHttpContextにアクセスしようとすると、NullReferenceを取得しますApplication_Start
。
私は再び強調します、これは実際に追加した場合にのみ機能します
services.AddSingleton<Microsoft.AspNetCore.Http.IHttpContextAccessor, Microsoft.AspNetCore.Http.HttpContextAccessor>();
私が書いたように。
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;
}
}
}
}
そして、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>()
);
他の答えに追加するだけです...
ASP.NETコア2.1で、あります拡張メソッド登録されます、正しい寿命とは:AddHttpContextAccessor
IHttpContextAccessor
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
// Other code...
}
私が思いついた最も正当な方法は、次のように静的実装にIHttpContextAccessorを注入することでした。
public static class HttpHelper
{
private static IHttpContextAccessor _accessor;
public static void Configure(IHttpContextAccessor httpContextAccessor)
{
_accessor = httpContextAccessor;
}
public static HttpContext HttpContext => _accessor.HttpContext;
}
次に、Startup ConfigureでIHttpContextAccessorを割り当てると、ジョブが実行されます。
HttpHelper.Configure(app.ApplicationServices.GetRequiredService<IHttpContextAccessor>());
サービスシングルトンも登録する必要があると思います。
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
この記事によると: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;
}
}
}
次に:
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;
}
}
次に:
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
}
public void Configure(IApplicationBuilder app)
{
app.UseStaticHttpContext();
app.UseMvc();
}
}
次のように使用できます。
using System.Web;
public class MyService
{
public void DoWork()
{
var context = HttpContext.Current;
// continue with context instance
}
}
スタートアップ中
services.AddHttpContextAccessor();
コントローラ内
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();
}
}
IHttpContextAccessor
、DIコンテナーがインスタンスを解決している場所でのみ使用できることにも言及する価値があります。