如何创建应在 Blazor 的每次页面单击或按钮单击时调用的自定义中间件

问题描述 投票:0回答:1

我想要的是,对于 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);
        }
    }`
.net session blazor timeout middleware
1个回答
0
投票

您可以在 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
等页面和所有常规路由页面上设置继承。

不是特别优雅!

© www.soinside.com 2019 - 2024. All rights reserved.