尝试在 mainlayout 中使用本地存储服务时的空引用

Null reference when trying to use localstorage service in mainlayout

我正在尝试在 blazor webassembly 应用程序中实现暗模式切换。 我注入了 localstorage,它可以在使用本地存储的其他页面上运行,但是当尝试在主布局 oninitalized 方法上实现它时,我在加载时遇到空引用错误。

public partial class MainLayout
{
[Inject]
    protected ILocalStorageService localStorage { get; set; }
protected override async Task OnInitializedAsync()
    {
        _darkmode = false;
        try
        {

            if (await localStorage.GetItemAsStringAsync("theme") == null) return;
            var mode = await localStorage.GetItemAsync<string>("theme");
            if (!string.IsNullOrEmpty(mode))
                _darkmode = mode == "darkmode" ? true : false;

            Themer.SetTheme(_darkmode);
            StateHasChanged();
        }
        catch (Exception ex)
        {
            _darkmode = false;

        }         

    }
}

这是我在主布局中与本地存储有任何关系时得到的错误。

暴击:Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100] 未处理的异常呈现组件:对象引用未设置到对象的实例。 System.NullReferenceException: 对象引用未设置为对象的实例。 在 SeekaPortal.Client.Shared.MainLayout.BuildRenderTree(RenderTreeBuilder __builder) 在 Microsoft.AspNetCore.Components.ComponentBase.<.ctor>b__6_0(RenderTreeBuilder 生成器) 在 Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder,RenderFragment renderFragment) 在 Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry) 在 Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()

Blazor 有一些奇怪的启动顺序行为,因为它在页面仍然是 运行 启动逻辑时呈现(好旧的异步,等待...)。不确定这是否是您的问题。这是我必须做的

@if (BootComplete) {
    <Router AppAssembly="@typeof(App).Assembly">
        <Found Context="routeData">
            <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <FocusOnNavigate RouteData="@routeData" Selector="h1" />
        </Found>
        <NotFound>
            <PageTitle>Not found</PageTitle>
            <LayoutView Layout="@typeof(MainLayout)">
                <p role="alert">Sorry, there's nothing at this address.</p>
            </LayoutView>
        </NotFound>
    </Router>
}
@inject IJSRuntime JS
@inject SavedData Saver


@code 
{

    // boot code. By hiding everything nothing starts until bootcomplete is set to true
    // that is done after the successful exit from OnInitializedAsync
    // App.Boot has to be async becuase it does 'IO'

    bool BootComplete = false;

    protected override async Task OnInitializedAsync() {
        EarWorm.Code.Util.Init(JS);
        await Saver.Boot();
        BootComplete = true;
    }
 }

即隐藏 UI 直到所有注入、初始化、状态读取等完成。我为整个应用程序都这样做了(如您所见,这是 App.razor),也许您需要在几页中使用它。