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

加载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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:45:55