加载ResX资源时忽略图片与文件引用,避免路径不存在引发ArgumentException
解决ResXResourceReader遇不存在文件引用抛异常的问题
这个问题我之前也遇到过,ResXResourceReader默认会尝试解析所有资源类型,包括那些指向本地文件的引用,一旦文件不存在就会直接抛出ArgumentException。不过有两种靠谱的办法可以跳过这些文件引用,只读取字符串资源:
方法一:手动解析ResX的XML结构
ResX本质是标准的XML文件,我们可以直接用XmlReader读取,筛选出需要的字符串资源,完全绕过文件引用的解析逻辑。这种方法最灵活,也不会触发任何资源实例化操作:
using System.Xml; using System.Collections.Generic; public static Dictionary<string, string> ExtractLocalizedStrings(string resxFilePath) { var localizedStrings = new Dictionary<string, string>(); using (XmlReader reader = XmlReader.Create(resxFilePath)) { while (reader.Read()) { // 找到<data>节点 if (reader.NodeType == XmlNodeType.Element && reader.Name == "data") { string resourceName = reader.GetAttribute("name"); string resourceType = reader.GetAttribute("type"); bool isFileRef = !string.IsNullOrEmpty(resourceType) && resourceType.Contains("ResXFileRef"); // 跳过文件引用资源,以及非字符串类型的资源 if (isFileRef || !string.IsNullOrEmpty(resourceType)) { continue; } // 读取<value>节点里的字符串内容 if (reader.ReadToDescendant("value")) { string resourceValue = reader.ReadElementContentAsString(); localizedStrings[resourceName] = resourceValue; } } } } return localizedStrings; }
方法二:利用ResXResourceReader的ResXDataNode模式
如果更倾向于使用官方的ResX API,可以开启UseResXDataNodes属性,让reader返回ResXDataNode对象而不是直接实例化资源。这样我们可以手动尝试获取值,并捕获异常跳过有问题的文件引用:
using System.Resources; using System.Collections; using System.Collections.Generic; public static Dictionary<string, string> ReadStringsSkipInvalidFiles(string resxFilePath) { var validStrings = new Dictionary<string, string>(); using (ResXResourceReader reader = new ResXResourceReader(resxFilePath)) { // 开启这个属性,返回ResXDataNode而不是直接实例化资源 reader.UseResXDataNodes = true; foreach (DictionaryEntry entry in reader) { if (entry.Value is not ResXDataNode node) { continue; } try { // 尝试获取资源值,文件不存在时会抛出ArgumentException object value = node.GetValue(null); // 只保留字符串类型的资源 if (value is string strValue) { validStrings[entry.Key.ToString()] = strValue; } } catch (ArgumentException) { // 跳过这个无效的文件引用资源 continue; } } } return validStrings; }
两种方法的对比
- 方法一完全脱离ResXResourceReader,自己解析XML,不会触发任何资源加载逻辑,适合只需要字符串、且想完全控制读取过程的场景。
- 方法二基于官方API,更符合.NET资源加载的规范,如果后续需要处理其他非字符串资源也更容易扩展,只是需要处理异常跳过无效项。
内容的提问来源于stack exchange,提问作者Simone
相关产品推荐
相关产品推荐

