Fix culture parameter being ignored in Blazor WebAssembly#1605
Fix culture parameter being ignored in Blazor WebAssembly#1605clairernovotny merged 7 commits intomainfrom
Conversation
Modified Resources.GetResource to use GetResourceSet with tryParents:false when a specific culture is provided, preventing unwanted fallback to neutral culture in Blazor WebAssembly environments. Added test to verify fix. Co-authored-by: clairernovotny <1427284+clairernovotny@users.noreply.github.com>
… Romanian test placeholders
Refactor resource retrieval logic to preserve previous behavior for null culture and ensure proper handling of exact and parent resource sets.
There was a problem hiding this comment.
Pull Request Overview
This PR fixes a Blazor WebAssembly-specific issue where explicitly passed culture parameters were being ignored in Humanizer's time-based methods, causing them to always return English results instead of the requested localized text.
- Modified the
Resources.GetResource()method to use a two-step resource retrieval approach that prevents premature fallback to neutral culture in WebAssembly environments - Added proper handling for explicit culture parameters by first attempting direct resource set access before falling back to standard ResourceManager behavior
- Updated test assertions to reflect correct resource string format
Reviewed Changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| src/Humanizer/Localisation/Resources.cs | Implemented two-step resource retrieval to fix culture parameter handling in Blazor WebAssembly |
| src/Humanizer.Tests/Localisation/ResourcesTests.cs | Updated test assertions to match corrected resource string format |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting
| // Only call GetResourceSet when we have an explicit, non-null culture to pass | ||
| // This preserves the previous behavior for callers that pass null (they fall through to GetString). | ||
| if (culture != null) | ||
| { | ||
| // Exact culture only, don't try parents and don't create resource sets. | ||
| var exactResourceSet = ResourceManager.GetResourceSet(culture, createIfNotExists: false, tryParents: false); | ||
| resource = exactResourceSet?.GetString(resourceKey); | ||
|
|
||
| if (resource == null) | ||
| { | ||
| // Check already-loaded parents without creating/adding new ResourceSets to the cache. | ||
| var parentResourceSet = ResourceManager.GetResourceSet(culture, createIfNotExists: false, tryParents: true); | ||
| resource = parentResourceSet?.GetString(resourceKey); | ||
| } | ||
| } | ||
|
|
||
| // Last resort: use the standard GetString which performs the full fallback chain and accepts null culture. | ||
| if (resource == null) | ||
| { | ||
| resource = ResourceManager.GetString(resourceKey, culture); |
There was a problem hiding this comment.
Avoiding fallback still calls GetString for first lookups
The new logic probes ResourceManager.GetResourceSet(culture, createIfNotExists: false, …) (and again with tryParents: true) but never allows the resource set to be created. When the satellite assembly has not yet been loaded—which is exactly the Blazor WebAssembly scenario this change targets—both calls return null and the method immediately falls back to ResourceManager.GetString, which performs the same neutral‑culture fallback and caches the result. As a result, explicit cultures are still ignored on the first lookup. To actually bypass fallback you need to load the exact culture’s resource set (e.g. createIfNotExists: true) before resorting to GetString.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
For now, I can only help with PRs you've created.
There was a problem hiding this comment.
@copilot address this, you ignored it just now:
The new logic probes ResourceManager.GetResourceSet(culture, createIfNotExists: false, …) (and again with tryParents: true) but never allows the resource set to be created. When the satellite assembly has not yet been loaded—which is exactly the Blazor WebAssembly scenario this change targets—both calls return null and the method immediately falls back to ResourceManager.GetString, which performs the same neutral‑culture fallback and caches the result. As a result, explicit cultures are still ignored on the first lookup. To actually bypass fallback you need to load the exact culture’s resource set (e.g. createIfNotExists: true) before resorting to GetString.
|
@copilot fix this: The new logic probes ResourceManager.GetResourceSet(culture, createIfNotExists: false, …) (and again with tryParents: true) but never allows the resource set to be created. When the satellite assembly has not yet been loaded—which is exactly the Blazor WebAssembly scenario this change targets—both calls return null and the method immediately falls back to ResourceManager.GetString, which performs the same neutral‑culture fallback and caches the result. As a result, explicit cultures are still ignored on the first lookup. To actually bypass fallback you need to load the exact culture’s resource set (e.g. createIfNotExists: true) before resorting to GetString. |
…ution Changed GetResource to use createIfNotExists: true when loading the exact culture's resource set. This ensures satellite assemblies are loaded in Blazor WebAssembly before falling back to GetString, preventing incorrect neutral culture results from being cached. Co-authored-by: clairernovotny <1427284+clairernovotny@users.noreply.github.com>
Fixed in commit 6be1677. Changed to use |
Problem
When using Humanizer in Blazor WebAssembly applications, explicitly passing a culture parameter to methods like
DateTime.Humanize(),TimeSpan.Humanize(), and related methods was being ignored, always returning English results even when proper localized resources were available.This issue was specific to Blazor WebAssembly and did not affect regular .NET applications. The
ToWords()methods worked correctly, but time-based humanization methods did not, despite all ultimately using the same resource loading mechanism.Root Cause
The
Resources.GetResource()method usedResourceManager.GetString(resourceKey, culture)which, in Blazor WebAssembly environments, can incorrectly fall back to the neutral/invariant culture (English) even when:This happens because:
Solution
Modified
Resources.GetResource()to ensure the exact culture's resource set is loaded before falling back:ResourceManager.GetResourceSet(culture, createIfNotExists: true, tryParents: false)to load the exact culture's resource set without parent fallback. This ensures the satellite assembly is loaded in Blazor WebAssembly scenarios.ResourceManager.GetString()behavior which performs the full fallback chain.This approach:
Changes
src/Humanizer/Localisation/Resources.cs: UpdatedGetResource()method to load the exact culture's resource set withcreateIfNotExists: truebefore falling back toGetString()After This Fix
All Humanizer methods that accept a culture parameter will now work correctly in Blazor WebAssembly:
DateTime.Humanize(culture: ...)TimeSpan.Humanize(culture: ...)DateOnly.Humanize(culture: ...)TimeOnly.Humanize(culture: ...)Fixes #2197
Fixes #1089
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.