.NET MAUI Blazor混合应用与Web应用本地化失效问题求助
看起来你在MAUI Blazor跨项目本地化的配置里踩了几个常见的坑,我来帮你一步步排查和解决:
1. 先补全资源文件的「关联空类」
你现在用IStringLocalizer<Resources>注入本地化器,但如果App.Shared项目里没有对应的空资源类,本地化器根本找不到你的.resx文件。
赶紧在App.Shared/Resources文件夹下新建一个空C#类:
namespace YourApp.App.Shared.Resources; // 命名空间要和你的项目实际命名空间一致 public class Resources { }
同时检查.resx文件的属性设置:
- 「生成操作」改为
Embedded Resource - 「自定义工具」设为
PublicResXFileCodeGenerator(确保生成可外部访问的资源类) - 在.resx设计器界面右上角,把「访问修饰符」选成
Public
2. 别乱改RootNamespace,统一项目命名空间
你把App.Shared的RootNamespace改成App.Web的命名空间,这会直接导致资源文件的归属混乱。正确的设置应该是:
App.Shared/Properties/AssemblyInfo.cs里:[assembly: RootNamespace("YourApp.App.Shared")]App.Web/Properties/AssemblyInfo.cs里:[assembly: RootNamespace("YourApp.App.Web")]
让两个项目的命名空间各自独立,资源文件的归属才清晰。
3. 让Web项目的本地化服务「扫描共享项目的资源」
你在App.Web里的AddLocalization默认只会扫描当前项目的资源,得手动告诉它去读取App.Shared里的资源:
// App.Web/Program.cs var sharedAssembly = typeof(YourApp.App.Shared.Resources.Resources).Assembly; builder.Services.AddLocalization(options => options.ResourcesPath = "Resources"); // 配置支持的文化列表 var supportedCultures = new[] { "en-GB", "en-US", "fr-FR", "en-ZA" }; var localizationOptions = new RequestLocalizationOptions() .SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures) // 用内置的Cookie提供器,别自己写中间件了 .AddInitialRequestCultureProvider(new CookieRequestCultureProvider { CookieName = CookieRequestCultureProvider.DefaultCookieName, CookieExpiration = TimeSpan.FromDays(365), Options = new CookieOptions { IsEssential = true } }); app.UseRequestLocalization(localizationOptions);
(自己写的LocalisationMiddleware逻辑有问题,内置的Cookie提供器已经能完美处理文化Cookie的读写,没必要重复造轮子)
4. 组件注入要精准匹配命名空间
确保UserMenu.razor里的导入和注入完全对应:
@using YourApp.App.Shared.Resources // 和资源类的命名空间保持一致 @inject IStringLocalizer<Resources> Localizer @Localizer["MyProfileLabel"]
同时检查Imports.razor里的@using ...Shared.Resources有没有写错命名空间。
5. 最后一步:强制清理重建
本地化配置很容易被旧的编译缓存干扰,按以下步骤操作:
- 右键解决方案 → 清理解决方案
- 手动删除所有项目的
bin和obj文件夹 - 重新生成整个解决方案
额外省心方案:用组件级本地化
如果你的组件都在App.Shared里,其实可以直接用组件对应的资源文件:比如把UserMenu.resx(及对应语言的UserMenu.en-GB.resx等)放在App.Shared/Layout/Top文件夹下,注入时直接写:
@inject IStringLocalizer<UserMenu> Localizer
这种方式不需要共享资源类,本地化器会自动匹配组件的命名空间和资源文件,出错概率更低。
内容来源于stack exchange

