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

.resx文件读取异常:获取到键而非对应值的问题排查

问题:无法从ErrorResources.resx获取本地化文本,返回结果始终是键值本身

我有一个错误处理类,在尝试显示异常消息时,无法从ErrorResources.resx文件获取对应的值。无论在该文件中写入什么内容,得到的始终是键而非值。以下是相关代码及文件结构:

错误处理类代码

public class ErrorHandler
{
    private readonly RequestDelegate _next;
    public ErrorHandler(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task Invoke(HttpContext context, ILogger<ErrorHandler> logger, IStringLocalizer<ErrorResources> localizer)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            await HandleAsync(context, ex, logger, localizer);
        }
    }

    private static Task HandleAsync(HttpContext context, Exception ex, ILogger<ErrorHandler> logger, IStringLocalizer<ErrorResources> localizer)
    {
        var statusCode = HttpStatusCode.InternalServerError;
        var errorMessageKey = "InternalServerError";

        var message = localizer[errorMessageKey].ToString();

        switch (ex)
        {
            case Application.CustomExceptions.PersonNotFoundException:
                statusCode = HttpStatusCode.NotFound;
                errorMessageKey = "PersonNotFound";
                message = localizer[errorMessageKey].ToString(); //此处得到的是PersonNotFound
                break;
           //其余代码
        }

    }
}

本地化中间件代码

public class Localizer
{
    private readonly RequestDelegate _next;

    public Localizer(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        var userLanguage = context.Request.Headers["Accept-Language"].ToString().Split(',').FirstOrDefault();
        var culture = string.IsNullOrEmpty(userLanguage) ? "en-US" : userLanguage;

        var defaultLanguage = string.IsNullOrEmpty(userLanguage) ? "en-US" : userLanguage;
        if (!string.IsNullOrEmpty(defaultLanguage))
        {
            try
            {
                CultureInfo.CurrentCulture = new CultureInfo(defaultLanguage);
                CultureInfo.CurrentUICulture = new CultureInfo(defaultLanguage);
            }
            catch (CultureNotFoundException)
            {
            }
        }
        await _next(context);
    }
}

Program.cs相关代码

builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddHttpContextAccessor();
builder.Services.AddSingleton<IStringLocalizer, StringLocalizer<ErrorResources>>();

文件结构

项目根目录下存在Resources文件夹,其中包含ErrorResources.resx(默认语言资源文件),以及对应的本地化资源文件(如ErrorResources.xx-XX.resx格式的文件)。


解决方案

1. 修正资源文件命名空间匹配

确保ErrorResources类的命名空间与资源文件生成的类命名空间一致:

  • 右键ErrorResources.resx → 属性
  • 设置「自定义工具命名空间」为项目根命名空间(或与ErrorResources类相同的命名空间)
  • 重新生成项目,检查ErrorResources.Designer.cs中的命名空间是否匹配

2. 调整中间件注册顺序

本地化中间件必须在错误处理中间件之前注册,否则错误处理逻辑执行时文化信息尚未生效:

// Program.cs中调整顺序
app.UseMiddleware<Localizer>();
app.UseMiddleware<ErrorHandler>();

3. 检查资源文件生成操作

确保所有ErrorResources系列文件的「生成操作」设置为Embedded resource:

  • 右键资源文件 → 属性
  • 修改「生成操作」为Embedded resource
  • 重新生成项目

4. 优化本地化服务注入方式

移除手动注册的单例本地化器,依赖框架自动处理泛型本地化服务:

// Program.cs中替换原有注入代码
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");
builder.Services.AddHttpContextAccessor();
// 无需手动注册IStringLocalizer,框架会自动解析IStringLocalizer<ErrorResources>

5. 验证文化设置有效性

在本地化中间件中添加日志,确认文化信息是否正确设置:

try
{
    CultureInfo.CurrentCulture = new CultureInfo(defaultLanguage);
    CultureInfo.CurrentUICulture = new CultureInfo(defaultLanguage);
    var logger = context.RequestServices.GetRequiredService<ILogger<Localizer>>();
    logger.LogInformation("当前文化设置为: {Culture}", defaultLanguage);
}
catch (CultureNotFoundException)
{
    var logger = context.RequestServices.GetRequiredService<ILogger<Localizer>>();
    logger.LogWarning("无效的文化格式: {Culture}", defaultLanguage);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 06:40:33