Blazor:为什么首先调用 NavigateTo 破坏生产中的作用域服务?

问题描述

我正在尝试使用 Blazor 制作网站。此错误不会发生在 IIS Express 上或来自 IIS 上的本地主机,但在外部网站上托管时,我总是遇到此问题。我第一次在第一页使用 Navigateto 时,我的所有服务都被重新初始化。

如果我在认示例应用的 NavMenu 中使用 NavLink 离开第一页,或者如果我已经导航离开或返回索引页面至少一次,服务将保持其状态。

我在调用 Navigateto 之前检查了我的服务,它们有值,但在执行后它们都丢失了。单身人士保持他们的状态。

为了隔离该错误,我创建了这个几乎没有修改的 Blazor Server 应用程序,并在下面包含了更改后的代码片段。

在 Startup.cs 中:

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor();
    services.AddSingleton<ConfigAccess>();
    services.AddScoped<BasicService>();
}

Index.razor:

@page "/"
@using Blazor_Bug_Isolation_Test.Services
@inject BasicService Basic
@inject ConfigAccess ConfigAccess
@inject NavigationManager navigationManager

<input @bind="Basic.Zipcode" placeholder="Postal code..." />
<input type="radio" @onclick="() => Basic.Option = BasicService.Options.Yes" name="options" id="yes"/>
<label for="yes">Yes</label>
<input type="radio" @onclick="() => Basic.Option = BasicService.Options.No" name="options" id="no" value="0" />
<label for="no">No</label>
<button class="btn btn-primary" @onclick='() => navigationManager.Navigateto(ConfigAccess.ApplicationRoot + "/Next")'>Proceed</button>

Next.razor:

@page "/Next"
@using Blazor_Bug_Isolation_Test.Services
@inject BasicService Basic
@inject ConfigAccess ConfigAccess
@inject NavigationManager navigationManager

<p>
    Zipcode: @Basic.Zipcode
</p>
<p>
    Radio: @Basic.Option
</p>
<button class="btn btn-primary" @onclick='() => navigationManager.Navigateto(ConfigAccess.ApplicationRoot + "/Last")'>Last</button>

和 BasicService.cs

namespace Blazor_Bug_Isolation_Test.Services
{
    public class BasicService
    {
        public Options Option { get; set; }
        public string Zipcode { get; set; }

        public enum Options
        {
            Yes = 1,No = 2
        }
    }
}

最后,我的文件布局的屏幕截图。 Screenshot

如果需要,我还可以包含 ConfigAccess 的代码,但应用程序根目录使用自定义 getter,因此它始终评估为正确的地址。

当我第一次从 Index.razor 单击 Proceed 时,保存到服务的任何输入都会丢失。如果有人知道原因,我将不胜感激。

更新:似乎第一个导航会导致 websocket 被删除并重新建立,这解释了为什么要重建范围服务。我仍然不知道是什么导致了这种行为。

解决方法

你能暂时将你的测试站点发布到 Github 并给我一个链接。根据您的描述,我认为问题出在您在 NavigateTo 中创建的 URL 中。 NavigateTo 实际上并没有做很多事情,它只是触发 LocationChanged 事件。路由器连接到这个并完成艰苦的工作。它将您正在构建的 URL 视为在其路由范围之外,并执行硬导航而不是简单地将新组件加载到 app 中。

三重检查 ConfigAccess.ApplicationRoot + "/Last" 正在创建什么。

,

将 NavigateTo 的第二个参数设置为 false 即可工作