You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core 8中Hellang Problem Details中间件本地化失败求助

.NET Core 8 API中Hellang Problem Details本地化失败的解决方案

问题场景

在Docker Linux镜像上运行的.NET Core 8 API项目中,尝试通过Hellang Problem Details对错误消息做本地化时,CustomizeProblemDetails委托内无法加载资源翻译——localizedErrorMessage返回键名"UserAlreadyExists",allStrings为空集合。核心代码如下:

builder.Services.AddProblemDetails(x => {
    x.CustomizeProblemDetails = ctx =>
    {
        var localizer = ctx.HttpContext.RequestServices.GetService<IStringLocalizer<ErrorHandling>>();
        var allStrings = localizer.GetAllStrings();
        var localizedErrorMessage = localizer[FailureCode.UserAlreadyExists.ToString()]; 
        // 后续处理逻辑
    };
});

已确认前提:

  • 请求的区域性配置正确(默认en-US)
  • Problem Details中间件在本地化中间件之后注册
  • 资源文件与DI配置无误(控制器中直接注入IStringLocalizer<ErrorHandling>可正常获取翻译)

虽可通过抛出异常时提前解析本地化内容规避,但希望在中间件中统一处理,避免重复注入和资源冗余。

原因分析

  1. Linux大小写敏感限制:Linux系统对文件名、路径的大小写严格匹配,若资源文件名(如ErrorHandling.en-US.resx)与对应类名(ErrorHandling)大小写不一致,会导致资源加载失败。
  2. 本地化上下文未绑定请求:直接通过RequestServices获取的IStringLocalizer可能未关联当前请求的区域性,或未加载包含父文化的资源。
  3. Docker镜像资源缺失:资源文件未被正确嵌入或复制到Docker镜像中,运行时无法读取。

解决方案

1. 修正资源文件命名与嵌入配置

确保资源文件名的大小写与对应类名完全一致(如类名为ErrorHandling,资源文件需命名为ErrorHandling.resx、ErrorHandling.en-US.resx),且存放路径的大小写与命名空间匹配。

同时在项目文件(.csproj)中确认资源文件被设置为嵌入资源:

<ItemGroup>
  <!-- 包含Resources目录下所有resx文件作为嵌入资源 -->
  <EmbeddedResource Include="Resources\**\*.resx" />
</ItemGroup>

2. 显式创建绑定请求区域性的本地化器

在CustomizeProblemDetails中通过IStringLocalizerFactory创建本地化器,显式传入当前请求的区域性,确保资源加载与请求上下文一致:

builder.Services.AddProblemDetails(x => {
    x.CustomizeProblemDetails = ctx =>
    {
        // 获取本地化工厂实例
        var localizerFactory = ctx.HttpContext.RequestServices.GetRequiredService<IStringLocalizerFactory>();
        // 获取当前请求的区域性
        var requestCulture = ctx.HttpContext.Features.Get<IRequestCultureFeature>();
        var currentCulture = requestCulture?.RequestCulture.Culture ?? CultureInfo.CurrentCulture;
        
        // 创建绑定ErrorHandling类的本地化器
        var localizer = localizerFactory.Create(typeof(ErrorHandling), typeof(ErrorHandling).Assembly.GetName().Name);
        
        // 显式指定区域性获取翻译文本
        var localizedErrorMessage = localizer.GetString(FailureCode.UserAlreadyExists.ToString(), currentCulture);
        // 获取所有字符串(包含父文化资源)
        var allStrings = localizer.GetAllStrings(includeParentCultures: true);
        
        // 将本地化后的消息赋值给ProblemDetails
        ctx.ProblemDetails.Detail = localizedErrorMessage;
    };
});

3. 确认中间件注册顺序

确保请求本地化中间件在Problem Details中间件之前注册,且位于路由中间件之前:

var app = builder.Build();

// 本地化中间件必须在路由之前注册
app.UseRequestLocalization();

app.UseRouting();
app.UseAuthorization();

// Problem Details中间件在路由、授权之后注册
app.UseProblemDetails();

app.MapControllers();
app.Run();

4. 验证Docker镜像资源完整性

使用官方.NET SDK镜像构建项目时,默认会包含嵌入资源;若为自定义构建步骤,需确保Dockerfile中包含资源文件的复制逻辑,避免镜像中缺失资源。

内容的提问来源于stack exchange,提问作者matt sharp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 08:50:34