Skip to content

Blazor AsyncLocal is null on first re-render following hot reload #45741

@Bouke

Description

@Bouke

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

When a hot reload is performed, any value stored with AsyncLocal is not available on the first render. Any subsequent renders will have the original AsyncLocal values available again. AsyncLocal is a common design approach for storing contextual information, e.g. Thread.CurrentPrincipal or CultureInfo.CurrentCulture as set by app.UseRequestLocalization().

Expected Behavior

AsyncLocal should flow and also be available on the rerender triggered by hot reload.

Steps To Reproduce

  1. Bouke/BlazorAsyncLocal@640aeb5
    Or:

    diff --git a/Pages/Index.razor b/Pages/Index.razor
    index b1a9fbd..b94d274 100644
    --- a/Pages/Index.razor
    +++ b/Pages/Index.razor
    @@ -1,9 +1,12 @@
     @page "/"
    +@using System.Globalization
     
     <PageTitle>Index</PageTitle>
     
     <h1>Hello, world!</h1>
     
    -Welcome to your new app.
    +<p>Welcome to your new app. You're on instance @AsyncLocalMiddleware.Instance.Value. Your current culture is @CultureInfo.CurrentCulture.Name.</p>
    +
    +<p><button class="btn btn-primary" @onclick="() => StateHasChanged()">Invoke StateHasChanged()</button></p>
     
     <SurveyPrompt Title="How is Blazor working for you?" />
    diff --git a/Program.cs b/Program.cs
    index 0a103e7..a47fbaf 100644
    --- a/Program.cs
    +++ b/Program.cs
    @@ -19,6 +19,9 @@ if (!app.Environment.IsDevelopment())
         app.UseHsts();
     }
     
    +app.UseMiddleware<AsyncLocalMiddleware>();
    +app.UseRequestLocalization("nl");
    +
     app.UseHttpsRedirection();
     
     app.UseStaticFiles();
    @@ -29,3 +32,22 @@ app.MapBlazorHub();
     app.MapFallbackToPage("/_Host");
     
     app.Run();
    +
    +public class AsyncLocalMiddleware
    +{
    +    private static int instances = 0;
    +    public static readonly AsyncLocal<int?> Instance = new();
    +    private readonly RequestDelegate next;
    +
    +    public AsyncLocalMiddleware(RequestDelegate next)
    +    {
    +        this.next = next ?? throw new ArgumentNullException(nameof(next));
    +    }
    +
    +    public async Task InvokeAsync(HttpContext context, ILogger<AsyncLocalMiddleware> logger)
    +    {
    +        Instance.Value = instances++;
    +        logger.LogInformation($"Set instance to {Instance.Value}");
    +        await next(context);
    +    }
    +}
  2. Run dotnet watch and open in browser. Notice that the page says:

    Welcome to your new app. You're on instance 13. Your current culture is nl.

  3. Change Pages/Index.razor in a way that triggers hot reload. E.g. change the heading to <h1>Hello, you!</h1>

  4. Notice that the page now says:

    Welcome to your new app. You're on instance . Your current culture is en-US.

  5. Click the button labeled "Invoke StateHasChanged()". Notice that the page now updates to the text from step 2:

    Welcome to your new app. You're on instance 13. Your current culture is nl.

Exceptions (if any)

No response

.NET Version

6.0.403

Anything else?

.NET SDK (reflecting any global.json):
Version: 6.0.403
Commit: 2bc18bf292

Runtime Environment:
OS Name: Mac OS X
OS Version: 13.1
OS Platform: Darwin
RID: osx-x64
Base Path: /usr/local/share/dotnet/sdk/6.0.403/

global.json file:
Not found

Host:
Version: 6.0.11
Architecture: x64
Commit: 943474ca16

.NET SDKs installed:
6.0.403 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.11 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.11 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Pillar: Dev ExperiencePriority:2Work that is important, but not critical for the releasearea-blazorIncludes: Blazor, Razor ComponentsbugThis issue describes a behavior which is not expected - a bug.copilot-candidatefeature-hot-reloadThis issue is related to the Hot Reload feaature

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions