自定义命名空间下ASP.NET Core MVC本地化失效问题求助
问题背景
公司项目使用自定义默认命名空间,导致本地化功能无法正常工作。字符串资源文件存放在Resources/Strings文件夹中,调试发现程序在以下路径搜索资源:
Resources.Strings.{my default namespace}.Controllers.HomeController
即系统将Resources.Strings添加在了默认命名空间的前面,导致无法找到正确的资源文件。在Visual Studio默认命名空间的新项目中,相同代码可正常运行。
相关代码
Program.cs 关键代码
// Add services to the container. builder.Services.AddControllersWithViews().AddViewLocalization(Microsoft.AspNetCore.Mvc.Razor.LanguageViewLocationExpanderFormat.Suffix); builder.Services.AddHttpContextAccessor(); // Add services to localization builder.Services.AddLocalization(options => { options.ResourcesPath = "Resources/Strings"; }); builder.Services.Configure<RequestLocalizationOptions>(options => { var suportedCultures = new[] { new CultureInfo("en-US"), new CultureInfo("de-DE"), new CultureInfo("pt-BR") }; options.DefaultRequestCulture = new RequestCulture("en-US"); options.SupportedUICultures = suportedCultures; }); var app = builder.Build(); app.UseRequestLocalization();
HomeController 关键代码
public class HomeController : Controller { private readonly IStringLocalizer _localizer; private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger, IHttpContextAccessor httpContextAccessor, IStringLocalizer<HomeController> localizer) { _logger = logger; _httpContextAccessor = httpContextAccessor; _localizer = localizer; } public IActionResult Index() { var localizedString = _localizer["WelcomeMessage"]; return View(); } // {...} }
失效原因
ASP.NET本地化系统默认会结合程序集的默认命名空间和资源路径来定位资源文件。使用IStringLocalizer<HomeController>时,系统会自动拼接ResourcesPath(Resources/Strings)、默认命名空间、控制器的命名空间(Controllers.HomeController)作为资源的完整查找路径。当默认命名空间与项目结构不匹配时,这个拼接逻辑会生成错误的资源路径,导致无法找到资源。
解决方法
方法1:调整资源文件的目录结构
按照Resources/Strings/{默认命名空间}/Controllers的结构存放资源文件。例如默认命名空间为MyCustomNamespace,则将HomeController.en-US.resx等文件放在Resources/Strings/MyCustomNamespace/Controllers目录下,让系统的自动拼接路径匹配实际文件位置。
方法2:手动指定资源名称(跳过自动拼接)
注入IStringLocalizerFactory,手动创建指定资源名称的本地化器,避免系统使用默认命名空间拼接:
public class HomeController : Controller { private readonly IStringLocalizer _localizer; private readonly IHttpContextAccessor _httpContextAccessor; private readonly ILogger<HomeController> _logger; public HomeController(ILogger<HomeController> logger, IHttpContextAccessor httpContextAccessor, IStringLocalizerFactory factory) { _logger = logger; _httpContextAccessor = httpContextAccessor; // 第一个参数是资源文件名(不含.resx后缀),第二个参数是资源所在的命名空间 _localizer = factory.Create("HomeController", "Resources.Strings"); } public IActionResult Index() { var localizedString = _localizer["WelcomeMessage"]; return View(); } // {...} }
此时资源文件直接放在Resources/Strings目录下即可,命名为HomeController.en-US.resx、HomeController.de-DE.resx等。
方法3:修改资源文件的自定义工具命名空间
右键资源文件(如HomeController.resx)→ 属性,将「自定义工具命名空间」修改为Resources.Strings,覆盖默认的自定义命名空间。这样系统会直接使用该命名空间查找资源,不再拼接默认命名空间。
注意:之前尝试将
ResourcesPath设置为{Default Namespace}.Resources/Strings无效,因为ResourcesPath指定的是文件系统中的路径,而非命名空间,不能直接添加命名空间前缀。
内容的提问来源于stack exchange,提问作者Filipe Cordella

