我已经通读了关于此事的所有其他帖子,我确信这不是重复的。
我正在构建一个 Razor 页面过滤器,以便在我的Startup.cs
类中使用,我需要访问HttpContext
。我通常会通过使用 ASP.NET Core 的 DI 功能的构造函数注入来做到这一点。我什至在Startup.cs
中拥有通常的services.AddHttpContextAccessor()
语句,并在项目的其他地方使用它。
由于我正在构建一个从IAsyncPageFilter
派生的 Razor 页面过滤器,并且是从Startup.cs
类创建的,因此看起来好像我无法注入它(因为它是由启动创建的,而不是注入的(。
以下是过滤器添加到Startup.cs
:
启动.cs(截图(
services.AddMvc(options =>
{
var policy = new AuthorizationPolicyBuilder()
.RequireAuthenticatedUser()
.Build();
options.Filters.Add(new AuthorizeFilter(policy));
options.Filters.Add(new RazorAsyncPageFilter(_logger, Configuration)); <---my filter
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
这是我的过滤器:
RazorAsyncPageFilter.cs
public class RazorAsyncPageFilter : IAsyncPageFilter
{
private readonly ILogger _logger;
private readonly IConfiguration _configuration;
public string[] Scopes { get; set; }
public string ScopeKeySection { get; set; }
public RazorAsyncPageFilter(ILogger logger, IConfiguration configuration)
{
_logger = logger;
_configuration = configuration;
}
public async Task OnPageHandlerSelectionAsync(PageHandlerSelectedContext context)
{
await Task.CompletedTask;
}
public async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{
VaultGraphServiceClient.OnMsalUiExceptionEvent += VaultGraphServiceClientOnOnMsalUiExceptionEvent;
await next.Invoke();
}
private void VaultGraphServiceClientOnOnMsalUiExceptionEvent(object sender, MsalUiRequiredException e)
{
_logger.LogInformation($"Triggered authentication exception: {e.Message}");
Scopes = new string[] { _configuration.GetValue<string>(ScopeKeySection) };
var properties = BuildAuthenticationPropertiesForIncrementalConsent(Scopes, e, **I_NEED_CONTEXT_HERE**);
new ChallengeResult(properties);
}
}
请注意从另一个类中的事件处理程序触发的方法调用中所需的上下文。我想将HttpContext
传递给过滤器类中的私有方法。
这是我尝试过的:
在
Startup.cs
中定义一个字段IHttpContextAccessor _httpContext
并将其传递给过滤器,但这显然不起作用,因为尚未建立该上下文。从其他方法传递上下文。这是更多的工作,并且充满了有关将其传递到后台线程的警告。
从我的调用
EventHandler
中注入上下文。不幸的是,这是从静态类调用的,据我所知,静态类中没有 DI 的概念。这是对的吗?此外,我正在使用一个EventHandler
委托,我用它来传递MsalUiRequiredException
对象,并且只能传递一个对象。也许我可以对event
类型使用不同的处理程序,但我对事件不够熟悉,无法理解如何做到这一点。我正在考虑创建一个自定义类来保存可以在其他地方注入/传递
MsalUiRequiredException
和HttpContext
,但这似乎也有些矫枉过正,或者可能是上面的 #2 问题。
有什么建议吗?
添加IHttpContextAccessor
作为构造函数参数
public RazorAsyncPageFilter(ILogger logger, IConfiguration configuration, IHttpContextAccessor httpContext)
{
_logger = logger;
_configuration = configuration;
_httpContext = httpContext;
}
并按类型添加过滤器
options.Filters.Add<RazorAsyncPageFilter>()