1

I'm creating a new website with Blazor and the NET8 framework using the boilerplate from Visual Studio 2022 Preview. The source code of this test is on GitHub.

As in my other post, I have already changed the ApplicationUser adding a new properties such as

public string? FirstName { get; set; }
public string? LastName { get; set; }

Now, in the file Index.razor under Components > Pages > Account > Manage, I like to allow the users to change or add those values.

enter image description here

The important thing is that on the left side, in the _NavManu.razor, there is a place where I display the username or the FirstName like that

<AuthorizeView>
    <Authorized>
        <div class="nav-item px-3">
            <NavLink class="nav-link" href="/Account/Manage">
                <span class="bi bi-person-fill" aria-hidden="true"></span> 
                @(usermanager.GetUserAsync(context.User).Result.FirstName ?? 
                  context.User.Identity?.Name)
            </NavLink>
        </div>
    </Authorized>
</AuthorizeView>

in the NavMenu.razor I added at the top of the page

@inject UserManager<ApplicationUser> usermanager

Now, when I try to save a new value for the FirstName for example, I invoke

if (Input.FirstName != _firstname)
{
    _user.FirstName = Input.FirstName;
    await UserManager.UpdateAsync(_user);
}

Immediately, I get an error in the NavMenu.razor

InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

The same code is working in the container of a NET7 Blazor application without issues.

enter image description here

Is there a way that I can fix it?

Update

After the message from H H, I added in the NavMenu.razor this code

@code {
    private string? Username;

    protected override async Task OnInitializedAsync()
    {
        var authState = await 
            AuthenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity.IsAuthenticated)
        {
            var fulldetails = await usermanager.GetUserAsync(user);
            Username = fulldetails.FirstName ?? user.Identity.Name;
        }
    }
}

With this, I can save an update as I can see here.

enter image description here

but if I click on any link, immediately I get this error

InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913. Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()

enter image description here

1 Answer 1

1

The main problem probably is @(usermanager.GetUserAsync(context.User).Result.FirstName ...

The (generated) BuildRenderTree method is not async and using .Result is asking for deadlocks.

When you await inside your SaveAsync() method a Render will happen (*) and that is where the conflict occurs.

The solution is to establish the userName in OnInitalizedAsync , not in the markup.

(*) I have to check that for SSR

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your comment. I changed the code but now I get a different error.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.