javascript - 当 20 分钟后应用 session 超时时,我在启动时收到 session 上的错误对象空引用

标签 javascript jquery blazor blazor-server-side

我在 Web 应用程序 Blazor 服务器端工作。当应用 session 超时达到 20 分钟时出现错误,然后应用程序将重定向到登录页面。

此代码块发生错误

  services.AddSession(options =>
        {
            options.IdleTimeout = TimeSpan.FromMinutes(20);
        });
    services.AddScoped<ISession>(_ => _.GetRequiredService<IHttpContextAccessor>().HttpContext.Session);

错误

Category: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost
EventId: 111
SpanId: b5f359c71bdf98dd
TraceId: 55c402b51115a74fe957d0762f8e004f
ParentId: 0000000000000000
RequestId: 800002a3-0000-f500-b63f-84710c7967bb
RequestPath: /_blazor
TransportConnectionId: GD0qeN4kpoisoFqdq7Lm_Q

Unhandled exception in circuit 'fsJjR_i80e4-G8BcnIas7mkmnqTlTY5vpTXVNEzo_Rg'.

Exception: 
System.NullReferenceException: Object reference not set to an instance of an object.
   at UC.AppRepository.UI.Startup.<>c.<ConfigureServices>b__4_1(IServiceProvider _) in D:\test repository\BackupBlazor\UC.AppRepository.UI\Startup.cs:line 67
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite callSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass2_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
   at Microsoft.AspNetCore.Components.ComponentFactory.<>c__DisplayClass7_0.<CreateInitializer>g__Initialize|1(IServiceProvider serviceProvider, IComponent component)
   at Microsoft.AspNetCore.Components.ComponentFactory.PerformPropertyInjection(IServiceProvider serviceProvider, IComponent instance)
   at Microsoft.AspNetCore.Components.ComponentFactory.InstantiateComponent(IServiceProvider serviceProvider, Type componentType)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.InstantiateChildComponentOnFrame(RenderTreeFrame& frame, Int32 parentComponentId)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
   at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
   at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

详情

我在 20 分钟后应用 session 超时

1 - 在 wwwroot/js 文件上创建 js,并具有函数 checkSessionTimeout

function checkSessionTimeout(currentUrl) {
    var sessionTimeout = 20 * 60 * 1000; // 2 minutes in milliseconds
    var lastActivity = new Date(Date.parse(sessionStorage.getItem("LastActivity"))); // get the last activity time from the client-side session
  
    if (new Date() - lastActivity > sessionTimeout) {
        /*console.log("reach 2 minutes")*/
        


sessionStorage.clear(); // clear the session storage

} 
else 
{
    setTimeout(function () { checkSessionTimeout(currentUrl); }, 1000); // check again in 1 second
    }
    
    }

checkSessionTimeout(window.location.href);

2 - 在 page.razor

@inject ISession Session;
protected override void OnInitialized()
{
DateTime now = DateTime.Now;
string nowString = now.ToString("yyyy-MM-ddTHH:mm:ss");
JS.InvokeVoidAsync("sessionStorage.setItem", "LastActivity", now);

}

3 - 组件加载后调用函数 checkSessionTimeout

protected override async Task OnAfterRenderAsync(bool firstRender)
{

var lastActivity = Session.GetInt32("LastActivity");

if ( TimeSpan.FromTicks(DateTime.Now.Ticks - lastActivity.Value) < TimeSpan.FromMinutes(20))
{
    navigationManager.NavigateTo("/Login/Login");
    return;
}
}

4- _host 文件主体最后一行 我添加以下内容:

<script src="~/assets/js/checksessiontimeout.js"></script>

5人入门类

public void ConfigureServices(IServiceCollection services)
        {
            
    services.AddHttpContextAccessor();
    services.AddHttpClient();
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSession();
    services.AddSession(options =>
    {
        options.IdleTimeout = TimeSpan.FromMinutes(20);
    });
services.AddScoped<ISession>(_ => _.GetRequiredService<IHttpContextAccessor>().HttpContext.Session); line 67 that give me error 
}

那么如何解决或防止此错误发生?

更新帖子

那么你能告诉我如何在不使用 HTTP 上下文的情况下实现 session 超时吗?

你能用代码告诉我吗

如果我避免使用 http 上下文,那么什么解决方案可以做到这一点

最佳答案

暂时忘记在 Blazor 服务器中使用 Session 吧。

Blazor 使用 websockets,而不是 http 请求/响应模型。因此:

  1. 您无法在 Blazor 中使用 HttpContextAccessor,因为 HttpContext 并不总是可用。当您刚打开 Blazor 应用程序时,它通常可以工作,但稍后,它会返回 null。

  2. 当没有HttpContext时,就没有Session。

  3. Session.Idletimeout 不适用于 Blazor,因为即使您处于事件状态(例如,单击按钮或在 blazor 应用内导航),它也会超时。

我可以想象一些允许您使用 Session 的技巧,但我会坚持使用受支持的内容。

此外,请注意 blazor session 与 http session (分别是 ASP.NET Core session )不同

关于javascript - 当 20 分钟后应用 session 超时时,我在启动时收到 session 上的错误对象空引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76098308/

相关文章:

javascript - jqGrid 可以优雅地降级吗?

javascript - 将文本区域的值绑定(bind)设置为 observableArray 的元素

c# - 在 IIS 上运行发布版本时出现 Blazor WebAssembly InvalidCastException

javascript - printThis.js 有时不打印内容

javascript - JS/jQuery - 页面加载时启动功能,每 x 秒一次,点击时启动功能

asp.net-core - Core 3.1 Blazor 应用程序中的 onclick 不起作用

blazor - vs2019 中 Blazor 项目类型的区别

javascript - ngTable - 服务器端分页 getData 错误

javascript - 无法在文本区域中添加更多文本

javascript - 使 onClick 按钮与 div 重叠内容