Skip to content

Fix culture persistence to not have public API#67367

Open
dariatiurina wants to merge 2 commits into
dotnet:mainfrom
dariatiurina:fix-culture-api
Open

Fix culture persistence to not have public API#67367
dariatiurina wants to merge 2 commits into
dotnet:mainfrom
dariatiurina:fix-culture-api

Conversation

@dariatiurina

@dariatiurina dariatiurina commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Fix culture persistence to not have public API

Summary

Reworks how WebAssembly culture persistence is configured so it no longer requires a public API surface. Instead of a public options class and a configuration callback overload, the behavior is now driven by the Components:UseCultureFromServer configuration value.

Changes

  • Removed the public WebAssemblyComponentsOptions class and its UseCultureFromServer property.
  • Removed the public AddInteractiveWebAssemblyComponents(this IRazorComponentsBuilder, Action<WebAssemblyComponentsOptions>?) overload. Only the parameterless AddInteractiveWebAssemblyComponents() remains.
  • Added internal WebAssemblyComponentsServiceOptions with a UseCultureFromServer property (defaults to true).
  • Added internal WebAssemblyComponentsServiceOptionsConfiguration, an IPostConfigureOptions<WebAssemblyComponentsServiceOptions> that reads the Components:UseCultureFromServer configuration value and binds it onto the options.
  • Updated PublicAPI.Unshipped.txt to drop the removed public API entries.
  • Updated the Components.TestServer startup to set Components:UseCultureFromServer via configuration instead of using the removed callback overload.

Details

  • The CultureStateProvider is now always registered as a scoped service and always added as a persistent component state registration for RenderMode.InteractiveWebAssembly. Previously this registration was conditional on UseCultureFromServer.
  • The opt-out is now applied at provider construction time: the scoped factory only calls CaptureCurrentCulture() when the resolved WebAssemblyComponentsServiceOptions.UseCultureFromServer is true. This moves the decision from registration time to resolution time while preserving the same observable behavior (no culture capture when disabled).
  • Default behavior is unchanged: culture is persisted from the server unless Components:UseCultureFromServer is set to false.

Testing

  • RazorComponentEndpointsStartup now toggles the behavior through the Components:UseCultureFromServer configuration key ("true"/"false") based on the existing EnforceServerCultureOnClient setting, exercising the new configuration path through the existing E2E culture scenarios.

Breaking Changes

  • The previously proposed public API (WebAssemblyComponentsOptions and the Action<WebAssemblyComponentsOptions>? overload) is removed. These were unshipped, so no released package is affected. Consumers configuring this behavior should now set the Components:UseCultureFromServer configuration value instead of passing an options callback.

Fixes #66829

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR removes the unshipped public options/configuration surface for interactive WebAssembly culture persistence and replaces it with an internal options type driven by the Components:UseCultureFromServer configuration key.

Changes:

  • Removes WebAssemblyComponentsOptions and the AddInteractiveWebAssemblyComponents(..., Action<WebAssemblyComponentsOptions>?) overload, leaving only the parameterless AddInteractiveWebAssemblyComponents().
  • Introduces internal WebAssemblyComponentsServiceOptions plus an IPostConfigureOptions<> to read Components:UseCultureFromServer.
  • Updates the test server startup to set Components:UseCultureFromServer via configuration, and updates PublicAPI.Unshipped.txt accordingly.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Components/WebAssembly/Server/src/WebAssemblyRazorComponentsBuilderExtensions.cs Removes the public overload and switches culture capture behavior to be driven by internal options/config.
src/Components/WebAssembly/Server/src/WebAssemblyComponentsServiceOptionsConfiguration.cs Adds post-configure hook to read Components:UseCultureFromServer from configuration.
src/Components/WebAssembly/Server/src/WebAssemblyComponentsServiceOptions.cs Adds internal options container (defaults UseCultureFromServer to true).
src/Components/WebAssembly/Server/src/WebAssemblyComponentsOptions.cs Removes the (unshipped) public options type.
src/Components/WebAssembly/Server/src/PublicAPI.Unshipped.txt Removes unshipped public API entries for the deleted options type and overload.
src/Components/test/testassets/Components.TestServer/RazorComponentEndpointsStartup.cs Updates test server wiring to set the new configuration key instead of using the removed overload.

@dariatiurina dariatiurina marked this pull request as ready for review June 23, 2026 11:23
@dariatiurina dariatiurina requested a review from a team as a code owner June 23, 2026 11:23
@dariatiurina dariatiurina requested a review from ilonatommy June 23, 2026 11:23
{
public void PostConfigure(string? name, WebAssemblyComponentsServiceOptions options)
{
var value = configuration["Components:UseCultureFromServer"];

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#66829 (comment)

Where do we check if localization has been wired up?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's on by default and will work only if localization has been wired up.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But what line of code checks that? From what I can see CaptureCurrentCulture() runs unconditionally regardless of localization being registered or not. I was expecting something that actually probes DI for localization.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add it now to PR

{
options.UseCultureFromServer = true;
}
if (string.Equals(value, "false", StringComparison.OrdinalIgnoreCase) || string.Equals(value, "0", StringComparison.OrdinalIgnoreCase))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since default value is true, isn't this "false" branch enough?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API Proposal: CulturePersistance from WebAssembly

4 participants