Skip to content

API review feedback: BrowserConfiguration shape/placement (#66393) #67336

@javiercn

Description

@javiercn

Review feedback on the public API proposed in #66393 (BrowserConfiguration for server-to-client configuration). Overall the feature is welcome and justified — Blazor apps commonly need server-authored browser boot options across render modes, and the current mechanisms are fragmented. The notes below are shape/placement suggestions; the endpoint-builder entry point is already in good shape.

Need / scenarios

  • Commonality: happy-path; audience: end-app developer.
  • Environments: flows wherever the server emits the boot document — static SSR/prerendered, Interactive Server, Interactive WebAssembly hosted by ASP.NET Core, and Auto. It is inert for purely client-side standalone WebAssembly with no server-rendered document — worth documenting.
  • Inputs naturally come from IHostEnvironment, logging options, request culture, and endpoint/middleware configuration.

Recommended shape changes

BrowserConfiguration (the root model)

  • Rename to BrowserOptions — it's an options bag; the Options suffix matches the rest of ASP.NET Core and avoids confusion with IConfiguration.
  • Seal it (options/DTO types are sealed by default; can unseal later).
  • LogLevel: use Microsoft.Extensions.Logging.LogLevel? instead of int? — the usage example passes a magic integer (LogLevel = 2 // Warning); a strongly-typed enum prevents that.
  • Make the nested Server/Ssr/WebAssembly properties non-null and initialized (get-only). The proposed usage config.Server.ReconnectionMaxRetries = 10 NREs unless each sub-object is pre-allocated — a pit-of-failure for the common path.

ServerBrowserOptions

  • Consider renaming to InteractiveServerBrowserOptions — here "Server" means interactive server rendering, not static SSR or the physical server; aligning with Blazor render-mode vocabulary avoids ambiguity.
  • Seal it.
  • ReconnectionRetryIntervalMillisecondsReconnectionRetryInterval of type TimeSpan?. Public .NET options express durations as TimeSpan; the serialized browser format can still use milliseconds internally.

SsrBrowserOptions

  • Seal it.
  • CircuitInactivityTimeoutMsCircuitInactivityTimeout (TimeSpan?).
  • DisableDomPreservation → positive PreserveDom (public options prefer positive Enable*/Allow*/Preserve* over Disable*; nullable still distinguishes "unset").

WebAssemblyBrowserOptions

  • Seal it.
  • EnvironmentVariables: expose as a non-null, initialized IDictionary<string, string> (get-only) rather than a settable concrete Dictionary<,> — avoids handing out a concrete type and avoids a null collection on the common path.

ConfigureBrowser (component)

  • Seal it.
  • Add [Parameter] (and [EditorRequired] on the required options) — component parameters need their attributes visible in the API shape and bound by the runtime.
  • Rename ConfigurationOptions for consistency with the renamed model.
  • Model HttpContext as a [CascadingParameter] (infrastructure that's absent once execution moves to the browser), not a normal settable parameter.

BrowserConfigurationHttpContextExtensions (the HttpContext accessor)

  • Move it out of Microsoft.AspNetCore.Http into the Blazor feature namespace, and rename to match the options type (GetBrowserOptions).
  • Why (grounded in the shipped API): feature-specific HttpContext extensions live in the feature's namespace, not the broad Microsoft.AspNetCore.Http one — of the 27 this HttpContext extension methods in the shipped public API, only 3 sit in Microsoft.AspNetCore.Http (core concepts like GetEndpoint/server variables); 20 are in Microsoft.AspNetCore.Authentication, 2 in Microsoft.AspNetCore.Routing, and the closest Blazor precedent — AcceptsInteractiveRouting — is in Microsoft.AspNetCore.Components.Routing. Placing this helper in the broad HTTP namespace would surface it on every HttpContext via IntelliSense.

What's already right

  • WithBrowserConfiguration(this RazorComponentsEndpointConventionBuilder, Action<…>) is the correct entry point: it's an endpoint-builder extension, so Microsoft.AspNetCore.Builder is the right namespace and returning the same builder follows the With* convention. (Only a consistency rename to track the options type — e.g. WithBrowserOptions/configureOptions — would be needed.)

Note on the serialized format

The <!--Blazor-Configuration:{}--> payload is effectively a wire format; consider treating its schema as versioned/internal so future changes aren't breaking, as called out in the proposal's Risks.


Filed as consolidated API-review feedback for #66393.

Metadata

Metadata

Labels

No fields configured for Feature.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions