.NET Core 6 Web API共享本地化失效问题求助
问题
我正尝试在.NET Core 6 Web API中实现包含两个资源文件的共享本地化功能,项目结构为:
- 项目根目录下有
Resources文件夹,存放SharedResources.resx(默认英文)和SharedResources.ru-RU.resx(俄语) SharedResources.cs文件位于Web.Facade命名空间下
相关代码
SharedResources.cs
namespace Web.Facade { public class SharedResources { } }
Startup.cs 配置
public void ConfigureServices(IServiceCollection services) { ... services.AddLocalization(options => options.ResourcesPath = "Resources"); ... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... var supportedCultures = new[] { "en-US", "ru-RU" }; var localizationOptions = new RequestLocalizationOptions().SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); app.UseRequestLocalization(localizationOptions); ... }
控制器使用示例(AuthController.cs)
[Route("api/v1/auth")] public class AuthController : ControllerBase { private readonly IAuthService authService; private readonly IStringLocalizer<SharedResources> localizer; private readonly ILogger<AuthController> logger; public AuthController( IAuthService authService, IStringLocalizer<SharedResources> localizer, ILogger<AuthController> logger) { this.authService = authService; this.localizer = localizer; this.logger = logger; } public async Task<IActionResult> RefreshToken([FromBody] RefreshTokenDTO refreshTokenDto) { if (!RefreshTokenDTO.IsValidModel(refreshTokenDto, out var errorMessage)) { return this.BadRequest(new ErrorResponse(this.localizer[errorMessage].Value)); } // 其他逻辑 } }
问题现象
携带Accept-Language: ru-RU请求头调用API时,返回的仍是默认英文字符串Invalid access or refresh tokens,而非俄语资源文件中的Некорректный access или refresh токен。
已尝试以下操作但无效:
- 将
SharedResources.cs移动到其他文件夹或项目根目录 - 修改
SharedResources.cs的命名空间 - 修改默认文化
仅当把SharedResources.ru-RU.resx重命名为SharedResources.resx时,才会返回俄语内容,但此时无论请求头是什么,都固定返回俄语,无法通过请求头切换语言。
希望实现通过请求头控制文化的共享本地化功能,请问遗漏了什么配置?
解决方案
1. 匹配资源文件命名与类的命名空间
.NET本地化系统会根据类的命名空间+类名+文化代码的规则匹配资源文件,需调整资源文件的存放路径或命名:
- 方式一:在
Resources文件夹下创建Web/Facade子目录,将SharedResources.resx和SharedResources.ru-RU.resx移动到该子目录中 - 方式二:直接在
Resources根目录下,将资源文件重命名为Web.Facade.SharedResources.resx和Web.Facade.SharedResources.ru-RU.resx
2. 显式配置本地化资源访问器
在ConfigureServices中添加本地化服务时,指定共享资源作为默认的本地化提供器,确保系统能正确关联资源:
services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddControllers() .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResources)); });
3. 调整请求本地化中间件的位置
确保app.UseRequestLocalization(localizationOptions)放在UseRouting、UseAuthorization等中间件之前,保证请求文化信息被优先识别:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } // 优先启用请求本地化 var supportedCultures = new[] { "en-US", "ru-RU" }; var localizationOptions = new RequestLocalizationOptions() .SetDefaultCulture(supportedCultures[0]) .AddSupportedCultures(supportedCultures) .AddSupportedUICultures(supportedCultures); app.UseRequestLocalization(localizationOptions); app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); }
4. 验证资源文件属性设置
右键资源文件 → 属性,确认:
- 自定义工具设置为
ResXFileCodeGenerator - 自定义工具命名空间与
SharedResources.cs的命名空间一致(即Web.Facade)
5. 检查资源键的匹配度
确保errorMessage变量的值与资源文件中的键完全一致(大小写敏感),比如资源文件中的键是Invalid access or refresh tokens,则errorMessage必须完全等于该字符串才能正确匹配。
内容的提问来源于stack exchange,提问作者Teddy Bashilov

