Search code examples
c#blazorfluent-ui

Blazor fluent ui DialogService, <FluentDialogProvider/> error


I am using .net8 and blazor with Fluent UI library and I get an error that no provider is found even though I added it to App.razor at the end of MainLayout.

Program.cs

builder.Services.AddHttpClient();
builder.Services.AddFluentUIComponents();

App.razor

<script src="_content/Microsoft.FluentUI.AspNetCore.Components/js/loading-theme.js" type="text/javascript"></script>
<script src="_content/Microsoft.FluentUI.AspNetCore.Components/Microsoft.FluentUI.AspNetCore.Components.lib.module.js" type="module" async></script>

MainLayout.razor

<FluentLayout>
    <FluentHeader>
        <Header/>
    </FluentHeader>

    <FluentStack Orientation="Orientation.Horizontal" Width="100%" Class="page--container">
        <NavMenu/>

        <FluentBodyContent>
            @Body
        </FluentBodyContent>
    </FluentStack>
</FluentLayout>

<FluentDialogProvider/>
<FluentToastProvider/>
<FluentTooltipProvider/>

Header.razor

[Inject] public IDialogService DialogService { get; set; }

private async Task ToggleThemeHandler()
{
    var dialog = DialogService.ShowDialogAsync<MenuPanel>(new DialogParameters
    {
        Alignment = HorizontalAlignment.Right
    });
    await dialog;
}

MenuPanel.razor

@implements IDialogContentComponent

<FluentDialogBody>
    Menu
</FluentDialogBody>

IDE Console

Unhandled exception rendering component: <FluentDialogProvider /> needs to be added to the main layout of your application/site. (Parameter 
'OnShowAsync')

System.ArgumentNullException: <FluentDialogProvider /> needs to be added to the main layout of your application/site. (Parameter 'OnShowAsyn
c') at Microsoft.FluentUI.AspNetCore.Components.DialogService.ShowDialogAsync[TData](Type dialogComponent, TData data, DialogParameters param
eters) in /_/src/Core/Components/Dialog/Services/DialogService-Dialog.cs:line 17 at Microsoft.FluentUI.AspNetCore.Components.DialogService.ShowDialogAsync[TDialog](DialogParameters parameters) in /_/src/Core/Components/Dialog/Services/DialogService-Dialog.cs:line 35 at Components.Layouts.MainLayout.Components.Header.ToggleThemeHandler() in **\Components\Layouts\MainLayout\Components\Header.razor:line 36

Solution

  • I would say, that is exactly the same issue described in a different modal library: https://github.com/Blazored/Modal/issues/543

    You are crossing interactivity boundaries. If you have @rendermode on your page, the boundary is here:

    <FluentLayout>
        <FluentHeader>
            <Header/>
        </FluentHeader>
    
        <FluentStack Orientation="Orientation.Horizontal" Width="100%" Class="page--container">
            <NavMenu/>
    
            <FluentBodyContent>
                @* Interactivity Boundary *@
                @Body
                @* Interactivity Boundary *@
            </FluentBodyContent>
        </FluentStack>
    </FluentLayout>
    
    

    Which means the <Header <FluentLayout, <FluentHeader, <FluentStack, etc is Server side rendered (SSR) and the page itself (@Body) has an interactivity, thus different context then SSR. They are not communicating with each other.

    You have to unify the interactivity between the dialog and your page.

    Here you have to either place all the Dialog elements inside the interactive page or put this into MainLayout.razor:

    @rendermode InteractiveServer
    

    Which will basically make all your pages InteractiveServer by default. (Which is something you might not want to, other solutions also exists).