如何在Blazor中检测整页刷新/重新加载

如何在Blazor中检测整页刷新/重新加载,blazor,blazor-server-side,Blazor,Blazor Server Side,我正在尝试检测Blazor中的页面刷新,以便在刷新发生之前,我将一些数据保存到本地存储,我尝试了Dispose,但我获取数据以保存的服务在此阶段不可用。 我还尝试了JavaScript的window.onbeforeunload,并在出现以下情况时调用C#方法: public static class SessionSaver { [JSInvokable] public static Task SaveServicesToSession() { View

我正在尝试检测Blazor中的页面刷新,以便在刷新发生之前,我将一些数据保存到本地存储,我尝试了Dispose,但我获取数据以保存的服务在此阶段不可用。 我还尝试了JavaScript的window.onbeforeunload,并在出现以下情况时调用C#方法:

public static class SessionSaver
{
    [JSInvokable]
    public static Task SaveServicesToSession()
    {
        ViewDataService viewData = (ViewDataService)GetMeSomeServiceLocator.Instance.GetService(typeof(ViewDataService));           
        ProtectedBrowserStorage protectedBrowserStorage = (ProtectedBrowserStorage)GetMeSomeServiceLocator.Instance.GetService(typeof(ProtectedSessionStorage));
        protectedBrowserStorage.SetAsync("ViewData", viewData);
        protectedBrowserStorage.SetAsync("AuthModel", viewData.AuthModel);            
        return Task.FromResult("Success.");
    }
}
Javascript:

 window.onbeforeunload  = () => {
        DotNet.invokeMethodAsync('BlazorStore9', 'SaveServicesToSession')
            .then(message => { console.log(message); });
        }
Startup.cs:嵌套类:

 public static class GetMeSomeServiceLocator
    {
        public static IServiceProvider Instance { get; set; }
    }
在配置方法中:

GetMeSomeServiceLocator.Instance = app.ApplicationServices;
重新加载页面时会调用JsInvokable,但出现错误:

System.InvalidOperationException:'无法从根提供程序解析作用域服务'BlazorStore9.Services.ViewDataService'


有什么办法可以解决这个问题吗?

根据@Mister Magoo和@mz1378的评论,我创建了一个适合我的解决方案。要从HTML属性(如onBeforeUnload)调用C#函数,必须使用JavaScript

让我们像这样创建一个名为
callDotNetFunctionFromJS
的java脚本函数(我在一个名为
callDotNetFunctionFromJS.js
的文件中创建了我的函数,该文件保存在客户机项目的
wwwroot
文件夹中):

然后创建要调用的函数:

[JSInvokable]
public static void PageAboutToBeReloaded()
{
    Console.WriteLine("Page will be refreshed");
}
重要提示:不要忘记添加
[JSInvokable]
,否则无法从java脚本函数调用C函数。此外,该方法必须是静态的。如果您的方法是非静态的,请参阅下面的“我的编辑”

在.razor文件中,让我们添加如下内容:

<body onbeforeunload="callDotNetFunctionFromJS('PageAboutToBeReloaded')"></body>
[JSInvokable]
public static void PageAboutToBeReloaded()
{
   callNonStaticFunction.Invoke();
}
protected override void OnInitialized()
{
    callNonStaticFunction = NonStaticFunction;
}
现在,如果您刷新希望收到通知的页面,您应该会看到输出“页面将被刷新”。专业提示:在浏览器控制台的设置中激活
Preserve log
,以防止刷新后控制台被清除

编辑:如果要调用非静态方法,请执行以下操作:

PageAboutToBeReloaded
方法必须如下所示:

<body onbeforeunload="callDotNetFunctionFromJS('PageAboutToBeReloaded')"></body>
[JSInvokable]
public static void PageAboutToBeReloaded()
{
   callNonStaticFunction.Invoke();
}
protected override void OnInitialized()
{
    callNonStaticFunction = NonStaticFunction;
}
要使其工作,必须在顶部添加操作:

private static Action callNonStaticFunction;
您的
OnInitialized()
应该如下所示:

<body onbeforeunload="callDotNetFunctionFromJS('PageAboutToBeReloaded')"></body>
[JSInvokable]
public static void PageAboutToBeReloaded()
{
   callNonStaticFunction.Invoke();
}
protected override void OnInitialized()
{
    callNonStaticFunction = NonStaticFunction;
}
现在,您可以实现在页面刷新时调用的非静态方法:

void NonStaticFunction()
{
    Console.WriteLine("DEBUG: huhu");
}

onbeforeunload是一个很好的选项,或者您可以在应用程序的正常工作流中找到其他事件来保存数据。我不知道你所说的“需要blazor的消息”是什么意思——也许可以在你的问题中添加一些细节,这样如果我们想从JavaScript调用c#方法,它就更针对blazor中的一个特定问题。JavaScript方法应该从blazor调用。它不能完全由JavaScript事件启动。你从哪里得到这样的印象?不是。因此,有一个函数可以显式地调用dotnet方法。(我已经做了您之前尝试的事情)如前所述-请用关于特定问题的特定问题更新您的问题,显示您尝试了什么以及您收到的任何错误。这就是这个网站的工作原理——专注于一个单一的问题,这样可以更容易地提供帮助。你试过你想用的方法吗?它说是的,但是没有代码,也没有错误消息。是的,纠正了,我错了,JavaScript调用c#instance方法,要求实例通过c#code传递。