-
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 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.
-
Change
Pages/Index.razor
in 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]