.NET Framework MVC中ResourceManager无法加载指定区域性RESX问题
看起来你遇到的核心问题是ResourceManager无法正确定位到en-US对应的卫星资源集,要么返回默认的de-CH资源,要么直接返回null。这通常是资源文件的配置、命名或者程序集加载环节出了问题,下面一步步帮你排查:
1. 检查资源文件的生成操作设置
这是最容易忽略的点:所有.resx文件(包括默认和区域性资源)的**生成操作(Build Action)**必须设置为Embedded Resource。如果设成了其他选项(比如Content),编译器不会把资源嵌入到程序集或生成卫星程序集,ResourceManager自然找不到。
操作步骤:右键资源文件 → 属性 → 生成操作,确认选择的是Embedded Resource。
2. 确认资源文件的命名规范与完全限定名
ResourceManager查找资源依赖完全限定名(命名空间 + 资源文件名,不带.resx后缀),如果这个名称写错了,就会找不到目标资源:
- 假设你的默认资源是
Create.resx,位于项目的Resources文件夹下,项目的根命名空间是MyMvcProject,那么它的完全限定名应该是MyMvcProject.Resources.Create。 - 对应的
en-US资源文件必须命名为Create.en-US.resx,且和默认资源在同一目录下,保证命名空间一致(可以在文件属性的“自定义工具命名空间”里确认)。
你可以用ILSpy这类工具打开主程序集,查看Resources节点下的资源名称,确保和你传入ResourceManager的nameOfResource完全一致。
3. 修正程序集加载的方式
你当前用Assembly.Load(assemblyName)加载程序集,很容易因为assemblyName拼写错误(比如遗漏版本号、公钥令牌)导致加载了错误的程序集,进而找不到资源。更可靠的方式是通过项目中已有的类型来获取程序集:
// 替换成你项目中任意一个类的Type,比如资源所在命名空间下的类 var assembly = typeof(YourProjectNamespace.Resources.SomeClass).Assembly; var resMgr = new ResourceManager("MyMvcProject.Resources.Create", assembly);
这种方式能确保加载的是包含资源的正确程序集。
4. 验证卫星程序集是否生成
当你编译项目时,区域性资源会被编译成卫星程序集,存放在bin目录下对应区域性的子文件夹中(比如bin\en-US\MyMvcProject.resources.dll)。如果这个文件夹或dll不存在,说明资源没有被正确编译:
- 清理项目后重新编译,检查是否生成了对应区域性的卫星程序集。
- 如果还是没生成,检查资源文件的“自定义工具”是否设置为
ResXFileCodeGenerator(默认应该是这个,用于生成资源类和编译资源)。
5. 理解tryParents参数的作用
你提到tryParents: true时返回默认的de-CH资源,tryParents: false返回null,这完全符合预期:
- 当
tryParents: true时,ResourceManager在找不到目标区域性(en-US)的资源时,会向上查找父区域性(比如en),如果还是找不到,就会回退到默认区域性(de-CH)。 - 当
tryParents: false时,找不到目标区域性的资源就直接返回null,这说明你的en-US资源根本没被ResourceManager找到,刚好印证了前面几个环节可能存在问题。
修正后的示例代码
结合上面的建议,你的ResourceSet属性可以改成这样:
public CultureInfo Culture { get; set; } public ResourceSet ResourceSet { get { // 用项目内的类型获取正确的程序集 var assembly = typeof(HomeController).Assembly; // 替换成你项目中的任意类 // 资源的完全限定名,根据你的实际命名空间调整 var resourceFullName = "MyMvcProject.Resources.Create"; var resMgr = new ResourceManager(resourceFullName, assembly); return resMgr.GetResourceSet(Culture, createIfNotExists: false, tryParents: true); } }
按照上面的步骤排查和修正后,应该就能正确加载en-US对应的资源集了。
内容的提问来源于stack exchange,提问作者awj

