Server Side Blazor应用中获取请求信息(含User-Agent)的正确方法
Great question—you’re exactly right that HttpContextAccessor isn’t a reliable choice for Server-Side Blazor, especially once the SignalR connection is up and running. Let’s break down the proper, dependable ways to capture the User-Agent from the initial request (since that’s where the browser sends this header).
Why HttpContextAccessor Fails
Quick context to set the stage: Server-Side Blazor uses SignalR for real-time communication. The HttpContext only exists during the initial page load and SignalR handshake. After that, when components render or handle user interactions, HttpContextAccessor will return null—so it’s not a trustworthy way to grab request details like User-Agent.
Method 1: Capture via Middleware + Scoped Service
This is the most flexible approach, as it makes the User-Agent available to any component in your app.
Create a Scoped Service to Store Request Details
This service will hold the User-Agent and be scoped to each user’s SignalR connection (meaning each user gets their own instance):public class RequestMetadataService { public string UserAgent { get; set; } = string.Empty; }Register the Service in
Program.cs
Add it as a scoped service in your app’s startup logic:builder.Services.AddScoped<RequestMetadataService>();Add a Middleware to Capture the User-Agent
Insert this middleware before the Blazor hub mapping inProgram.csto catch the initial request:app.UseRouting(); // Custom middleware to grab User-Agent from the initial request app.Use(async (context, next) => { var metadataService = context.RequestServices.GetRequiredService<RequestMetadataService>(); if (context.Request.Headers.TryGetValue("User-Agent", out var userAgent)) { metadataService.UserAgent = userAgent.ToString(); } await next.Invoke(); }); app.UseAuthentication(); app.UseAuthorization(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host");Use the Service in Any Blazor Component
Inject the service and access the User-Agent wherever you need it:@inject RequestMetadataService RequestMetadata <div> <p>Your Browser User-Agent:</p> <pre>@RequestMetadata.UserAgent</pre> </div>
Method 2: Pass from _Host.cshtml to Blazor Components
If you’re using prerendering, you can grab the User-Agent directly in _Host.cshtml and pass it to your root component:
Update
_Host.cshtml
Access theHttpContextand pass the User-Agent as a parameter to theAppcomponent:@{ Layout = null; var userAgent = Context.Request.Headers["User-Agent"].ToString(); } <component type="typeof(App)" render-mode="ServerPrerendered" param-UserAgent="@userAgent" />Receive the Parameter in
App.razor
You can use it directly here or pass it to the scoped service for global access across components:@inject RequestMetadataService RequestMetadata [Parameter] public string UserAgent { get; set; } = string.Empty; @code { protected override void OnInitialized() { // Store in the service so other components can access it RequestMetadata.UserAgent = UserAgent; } }
Both methods work reliably because they capture the User-Agent from the initial HTTP request (where it’s always available) and make it accessible throughout the Blazor app’s lifecycle, even after the SignalR connection is established.
内容的提问来源于stack exchange,提问作者John D'Alessandro

