ActionController.HttpContext 什么时候设置?
When is ActionController.HttpContext set?
我正在尝试实现一个 ASP.NET 核心 MVC 网络应用程序,类似于 Jason Taylor 的 CleanArchitecture design. In the WebUi "layer" I try to implement an abstraction of an IIdentityService
in which I want to access the ClaimsPrincipal 与当前 HttpRequest
关联。
在对 github 上的源代码进行一些挖掘之后,我发现 Controller.User
属性 源于 ControllerBase.HttpContext? which is derived from ControllerContext which in turn is derived from ActionContext,其中 HttpContext
属性 定义为
/// <summary>
/// Gets or sets the <see cref="Http.HttpContext"/> for the current request.
/// </summary>
/// <remarks>
/// The property setter is provided for unit test purposes only.
/// </remarks>
public HttpContext HttpContext
{
get; set;
}
我在这里进入了死胡同。我假设 属性 是由一些中间件初始化的(即来自 Microsoft.Identity 的 .AddAuthentication() / .AddAuthorization()),但我想确认这一点,所以我知道如何获得对我服务中的那个对象。
IPrincipal
的其他来源,ClaimsPrincipal
我从中找到
System.Web.HttpContext.Current.User
ClaimsPrincipal.Current
Thread.CurrentPrincipal
IHttpContextAccessor _httpContextAccessor;
var principal = _httpContextAccessor.HttpContext?.User;
使用 IHttpContextAccessor here 的文档,但我无法弄清楚 Controller.User
指向的是哪个。
@JHBonarius 在评论中向正确的方向暗示后,我在 the official documentation
中找到了一个记录案例
Use HttpContext from custom components
For other framework and custom components that require access to
HttpContext, the recommended approach is to register a dependency
using the built-in Dependency Injection (DI) container. The DI
container supplies the IHttpContextAccessor to any classes that
declare it as a dependency in their constructors:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllersWithViews();
builder.Services.AddHttpContextAccessor();
builder.Services.AddTransient<IUserRepository, UserRepository>();
In the following example:
UserRepository declares its dependency on IHttpContextAccessor. The
dependency is supplied when DI resolves the dependency chain and
creates an instance of UserRepository.
public class UserRepository : IUserRepository {
private readonly IHttpContextAccessor _httpContextAccessor;
public UserRepository(IHttpContextAccessor httpContextAccessor) =>
_httpContextAccessor = httpContextAccessor;
public void LogCurrentUser()
{
var username = _httpContextAccessor.HttpContext.User.Identity.Name;
// ...
}
}
我正在尝试实现一个 ASP.NET 核心 MVC 网络应用程序,类似于 Jason Taylor 的 CleanArchitecture design. In the WebUi "layer" I try to implement an abstraction of an IIdentityService
in which I want to access the ClaimsPrincipal 与当前 HttpRequest
关联。
在对 github 上的源代码进行一些挖掘之后,我发现 Controller.User
属性 源于 ControllerBase.HttpContext? which is derived from ControllerContext which in turn is derived from ActionContext,其中 HttpContext
属性 定义为
/// <summary>
/// Gets or sets the <see cref="Http.HttpContext"/> for the current request.
/// </summary>
/// <remarks>
/// The property setter is provided for unit test purposes only.
/// </remarks>
public HttpContext HttpContext
{
get; set;
}
我在这里进入了死胡同。我假设 属性 是由一些中间件初始化的(即来自 Microsoft.Identity 的 .AddAuthentication() / .AddAuthorization()),但我想确认这一点,所以我知道如何获得对我服务中的那个对象。
IPrincipal
的其他来源,ClaimsPrincipal
我从中找到
System.Web.HttpContext.Current.User
ClaimsPrincipal.Current
Thread.CurrentPrincipal
IHttpContextAccessor _httpContextAccessor;
var principal = _httpContextAccessor.HttpContext?.User;
使用 IHttpContextAccessor here 的文档,但我无法弄清楚 Controller.User
指向的是哪个。
@JHBonarius 在评论中向正确的方向暗示后,我在 the official documentation
中找到了一个记录案例Use HttpContext from custom components
For other framework and custom components that require access to HttpContext, the recommended approach is to register a dependency using the built-in Dependency Injection (DI) container. The DI container supplies the IHttpContextAccessor to any classes that declare it as a dependency in their constructors:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.AddHttpContextAccessor(); builder.Services.AddTransient<IUserRepository, UserRepository>();
In the following example:
UserRepository declares its dependency on IHttpContextAccessor. The dependency is supplied when DI resolves the dependency chain and creates an instance of UserRepository.
public class UserRepository : IUserRepository { private readonly IHttpContextAccessor _httpContextAccessor; public UserRepository(IHttpContextAccessor httpContextAccessor) => _httpContextAccessor = httpContextAccessor; public void LogCurrentUser() { var username = _httpContextAccessor.HttpContext.User.Identity.Name; // ... } }