Search code examples
c#asp.net-coreerror-handlingblazorant-design-blazor

Blazor Server: Duplicate Notifications Issue When Updating ApplicationState ErrorMessage


I have a notify dublication when AppState.ErrorMessage changes such as AppState.ErrorMessage = "Some error". When I click the button, where I set value, I receive notificaiton two times

MainLayout

public partial class MainLayout : IDisposable
{
    [Inject]
    public required INotificationService Notice { get; set; }

    [CascadingParameter]
    public ApplicationState? AppState { get; set; }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender && AppState is not null)
        {
            AppState.OnNotification += OnNotificationHandler;
        }
        await base.OnAfterRenderAsync(firstRender);
    }

    public void Dispose()
    {
        if (AppState is not null)
        {
            AppState.OnNotification -= OnNotificationHandler;
        }
    }

    private void OnNotificationHandler()
    {
        InvokeAsync(ShowNotification);
    }

    private async Task ShowNotification()
    {
        if (AppState is not null)
        {
            await Notice.Error(new NotificationConfig()
            {
                Message = AppState.ErrorMessage
            });
        }
    }
}

ApplicationState

public class ApplicationState
{
    private string _errorMessage = string.Empty;

    public string ErrorMessage
    {
        get => _errorMessage;
        set
        {
            if (!string.Equals(_errorMessage, value) &&  !string.IsNullOrWhiteSpace(value))
            {
                _errorMessage = value;
                ShowError();
            }
            else
            {
                _errorMessage = value;
            }
        }
    }

    public event Action? OnNotification;

    public void ShowError()
    {
        OnNotification?.Invoke();
        _errorMessage = string.Empty;
    }
}

What I did

  • Implemented a notification flag
  • cleaned an error message
  • introduced event subscription management.

Maybe the problem is with rendermode?

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="/" />
    <link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
    <link rel="stylesheet" href="@Assets["app.css"]" />
    <link rel="stylesheet" href="@Assets["Client.styles.css"]" />
    <ImportMap />
    <link rel="icon" type="image/png" href="favicon.png" />
    <HeadOutlet @rendermode="new InteractiveServerRenderMode(prerender: false)" />
</head>

<body>
    <Routes @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    <AntContainer @rendermode="new InteractiveServerRenderMode(prerender: false)" />
    <script src="_framework/blazor.web.js"></script>
</body>

</html>

Solution

  • The problem was in rendermode:

    <Routes @rendermode="InteractiveServer" />
    
    <AntContainer @rendermode="RenderMode.InteractiveWebAssembly" /> //problem was here *change from InteractiveServer to InteractiveWebAssembly.