1
votes

we are incorporating Blazor into our existing .net5.0 project. Separate section of the application is using blazor. When a user enters that section and changes the view by clicking a link, the view for all users will change to that corresponding view.

e.g. User A is viewing pageA, User B goes to page A and then clicks a link that would change the component to pageB. User A and User B are now pageB.

Project is on an IIS Server

ToCNode.razor

@using DataObjects.Help
@inject EditorState EditorState

<ul>
    @foreach (var child in Children)
    {
        <ToCNode wikiNodeDto="@child" />
    }
</ul>
@code {

    [Parameter]
    public WikiNodeDto wikiNodeDto { get; set; }
    IEnumerable<WikiNodeDto> Children { get; set; }
    string DisplayName { get; set; }
    bool ShowChildren { get; set; } = false;

    protected override void OnInitialized()
    {
        DisplayName = wikiNodeDto.Name;
        Children = wikiNodeDto.Children;
        base.OnInitialized();
    }
    void ToggleVisibility()
    {
        ShowChildren = !ShowChildren;
    }
    void SetContent()
    {
        EditorState.SetEditorContent(wikiNodeDto);
    }
}

Content.razor

@using Components
@using DataObjects.Help
@using Models.Dbo
@inject DataManagers.Interfaces.IHelpManager HelpManager
@inject EditorState EditorState
@implements IDisposable

<div class="container body-content" id="bodyContent">
    <div id="alertPlaceholder" style="margin-top:15px;"></div>
    <div class="row">
        <div class="col-xl-3" style="height:calc(100vh - 110px); overflow-y: auto; overflow-x: auto">
            <h3 style="text-align: center; color: #17a2b8;">Table of Contents</h3>
            <ToCNode wikiNodeDto="@nodes[0]" /> <!--root note-->
        </div>
        <div class="col-xl-9" style="height: calc(100vh - 110px); overflow-y: auto">
            <Editor savedContent="@EditorState.EditorContent" OnLoadArticle="@EditorState.OnLoadArticle" />
        </div>
    </div>
</div>

@code {

    public IList<WikiNodeDto> nodes;
    public string editorContent = "";

    protected override void OnInitialized()
    {
        nodes = HelpManager.GetAllWikiNodesDto();
        EditorState.wikiNodeDto = HelpManager.GetAllWikiNodesDto()[0];
        EditorState.EditorContent = EditorState.wikiNodeDto.Description;
        EditorState.OnLoadArticle = true;
        EditorState.OnChange += OnChangeHandler;
    }

    private async void OnChangeHandler()
    {
        await InvokeAsync(StateHasChanged);
    }

    public void Dispose()
    {
        EditorState.OnChange -= OnChangeHandler;
    }
}

EditorState.cs

using DataObjects.Help;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Components
{
    public class EditorState
    {
        public WikiNodeDto wikiNodeDto { get; set; }
        public string EditorContent { get; set; }
        public bool OnLoadArticle { get; set; }

        public event Action OnChange;

        public void SetEditorContent(WikiNodeDto nodeDto)
        {
            wikiNodeDto = nodeDto;
            EditorContent = nodeDto.Description;
            OnLoadArticle = true;
            NotifyStateChanged();
        }

        public void NotifyStateChanged()
        {
            OnChange?.Invoke();
        }
    }
}

Startup.cs

services.AddSingleton<EditorState>(); //this was the issue
services.AddScoped<EditorState>(); // This is what it should be

Edit: Updated with more information

2nd Edit: Updated with Startup.cs

2
We still need to see that 1 line from Startup.cs where you register EditorState. - Henk Holterman
Updated the question with the answer. thanks for your help! - scaborski
All these answers asume the same instance of the server. This is not true in all hosting environments. So be careful what works in dev may not in prod. - Brian Parker
@BrianParker - I haven't seen any examples of Scale-out for Blazor server. Do you think that is even possible? - Henk Holterman
@BrianParker - in this case, it was the same instance of the server. This project is hosted on an IIS server and is used within an internal network. - scaborski

2 Answers

1
votes

I'll take a guess: EditorState is a singleton instance. Shared by all users.

You should add the code for how it is created and managed. It is now not clear if it is injected or cascaded or just static.

1
votes

As per @Henk Holterman, issue was that the EditorState was added to the startup as a Singleton.

Changed it to AddScoped and is working as it should.