-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Description
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
-
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); + } +}
-
Run
dotnet watchand open in browser. Notice that the page says:Welcome to your new app. You're on instance 13. Your current culture is nl.
-
Change
Pages/Index.razorin a way that triggers hot reload. E.g. change the heading to<h1>Hello, you!</h1> -
Notice that the page now says:
Welcome to your new app. You're on instance . Your current culture is en-US.
-
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]