我想要的是,对于 Blazor 操作的每次点击,它都应该到达我的中间件,以便我可以检查超时。
请注意: 我确实尝试过脚本函数来捕获单击/按键操作,但它们无法正常工作, 即使用户随机点击,它也会使用户注销。 我无法在 Blazor 中使用 Microsoft.Session,因此无法对其实现超时逻辑。 因此,如果用户单击任何页面,或者调用任何特定的类对象,则应该调用此中间件..`
`public class SessionTimeoutMiddleware
{
private readonly RequestDelegate _next;
private ATMTreeViewRepository _atmTreeService { get; set; }
private IServiceProvider _serviceProvider { get; set; }
public SessionTimeoutMiddleware(RequestDelegate next, ATMTreeViewRepository atmTreeService, IServiceProvider serviceProvider)
{
_next = next;
_atmTreeService = atmTreeService;
_serviceProvider = serviceProvider;
}
public async Task InvokeAsync(HttpContext httpContext)
{
if (_atmTreeService.sessionTime == null)
{
_atmTreeService.sessionTime = DateTime.Now;
}
else
{
double minutes = DateTime.Now.Subtract(_atmTreeService.sessionTime.Value).TotalMinutes;
if (minutes > 5)
{
using (var scope = _serviceProvider.CreateScope())
{
var _navigationManager = scope.ServiceProvider.GetRequiredService<NavigationManager>();
if (_navigationManager != null)
_navigationManager.NavigateTo($"{_navigationManager.BaseUri}");
}
}
else
{
_atmTreeService.sessionTime = DateTime.Now;
}
}
await _next(httpContext);
}
}`
您可以在 MainLayout 中实现它来检查所有导航事件。它在导航事件之前为导航管理器注册一个处理程序。它只是向输出窗口写入一行来演示如何执行此操作。
@using System.Diagnostics;
@inherits LayoutComponentBase
@inject NavigationManager NavManager
@implements IDisposable
<PageTitle>SO76998619</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
@code {
private IDisposable? _disposable;
protected override void OnInitialized()
{
_disposable = this.NavManager.RegisterLocationChangingHandler(OnBeforeNavigateAsync);
base.OnInitialized();
}
private ValueTask OnBeforeNavigateAsync(LocationChangingContext context)
{
Debug.WriteLine("Just checking before navigating");
return ValueTask.CompletedTask;
}
public void Dispose()
{
_disposable?.Dispose();
}
}
如果您想检查每个 UI 事件,您需要创建一个实现不同
IHandleEvent
处理程序的基本组件。
这是一个演示组件,当前再次记录到输出。
using Microsoft.AspNetCore.Components;
using System.Diagnostics;
namespace SO76998619.Shared
{
public class MyComponentBase : ComponentBase, IHandleEvent
{
async Task IHandleEvent.HandleEventAsync(EventCallbackWorkItem item, object? obj)
{
Debug.WriteLine("Do a quick check before executing UI Event");
var uiTask = item.InvokeAsync(obj);
await this.CheckIfShouldRunStateHasChanged(uiTask);
this.StateHasChanged();
}
protected async Task<bool> CheckIfShouldRunStateHasChanged(Task task)
{
var isCompleted = task.IsCompleted || task.IsCanceled;
if (!isCompleted)
{
this.StateHasChanged();
await task;
return true;
}
return false;
}
}
}
在基本模板中,您需要在
NavMenu
等页面和所有常规路由页面上设置继承。
不是特别优雅!