【问题标题】:How to get Name by string Value from a .NET resource (RESX) file如何从 .NET 资源 (RESX) 文件中按字符串值获取名称
【发布时间】:2023-03-07 17:54:01
【问题描述】:

这是我的 RESX 文件的样子:

Name            Value        Comments
Rule_seconds    seconds      seconds
Rule_Sound      Sound        Sound

我想要的是: 按字符串值命名,如下所示:

public string GetResxNameByValue(string value)
{
// some code to get name value
}

并像下面这样实现它:

string str = GetResxNameByValue("seconds");

这样str 将返回Rule_seconds

谢谢!

【问题讨论】:

  • 这似乎只有在资源文件确保没有重复值的情况下才能实现,否则您可能会返回意外的资源键。即,如果您有两个名称/键(Time_Second、Sequence_Second),它们的值都是“秒”。当您期望另一个时,您可能会得到“Time_second”的名称。

标签: c# .net resx


【解决方案1】:

这可以工作

private string GetResxNameByValue(string value)
    {
            System.Resources.ResourceManager rm = new System.Resources.ResourceManager("YourNamespace.YourResxFileName", this.GetType().Assembly);


        var entry=
            rm.GetResourceSet(System.Threading.Thread.CurrentThread.CurrentCulture, true, true)
              .OfType<DictionaryEntry>()
              .FirstOrDefault(e => e.Value.ToString() ==value);

        var key = entry.Key.ToString();
        return key;

    }

加上一些额外的错误检查..

【讨论】:

  • 谢谢,如果资源文件在程序集中而不是项目中的实际 (RESX) 文件怎么办?
  • 您可以在 ResourceManager 构造函数中指定嵌入资源的程序集。但是您仍然必须知道资源库名称。如果您不这样做,我认为您可以使用 Assembly.GetMainfestResourceNames 找出哪些资源嵌入到程序集中
  • @jure: 是否可以从资源中返回所有的键值对?
【解决方案2】:

你可以通过key直接访问:

    public  string gtresource(string rulename)
    {
        string value = null;
        System.Resources.ResourceManager RM = new System.Resources.ResourceManager("CodedUITestProject1.Resource1", this.GetType().Assembly);
        value = RM.GetString(rulename).ToString();

        if(value !=null && value !="")
        {
            return value;

        }
        else
        {
            return "";
        }

    }

【讨论】:

  • 在 7 行代码中,我看到了几个需要解决的问题: 首先 RM.GetString(rulename) 已经返回了一个字符串。无需致电ToString()。其次,RM.GetString(rulename) 可以返回 null 是没有找到资源,这会引发一个NullReferenceException。第三,由于NullReferenceException,将永远不会使用空值到达if(value !=null &amp;&amp; value !="")。最后,您可以将所有 if 替换为 return RM.GetString(rulename) ?? string.Empty;
  • 这并没有解决原始问题,即您作为解决方案发布的内容的“反向”。需要通过特定值检索它们的键...
【解决方案3】:

以防万一它可以帮助任何人。这个 ResourceHelper 的灵感来自 jureMohan Singh Saini

using System.Collections;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Threading;

public class ResourceHelper
{
    /// <summary>
    ///     ResourceHelper
    /// </summary>
    /// <param name="resourceName">i.e. "Namespace.ResourceFileName"</param>
    /// <param name="assembly">i.e. GetType().Assembly if working on the local assembly</param>
    public ResourceHelper(string resourceName, Assembly assembly)
    {
        ResourceManager = new ResourceManager(resourceName, assembly);
    }

    private ResourceManager ResourceManager { get; set; }

    public string GetResourceName(string value)
    {
        DictionaryEntry entry = ResourceManager.GetResourceSet(Thread.CurrentThread.CurrentCulture, true, true).OfType<DictionaryEntry>().FirstOrDefault(dictionaryEntry => dictionaryEntry.Value.ToString() == value);
        return entry.Key.ToString();
    }

    public string GetResourceValue(string name)
    {
        string value = ResourceManager.GetString(name);
        return !string.IsNullOrEmpty(value) ? value : null;
    }
}

【讨论】:

  • 对如何在引用的项目中引用字符串资源有任何想法吗?尝试引用它时,我不断收到异常。
  • 我找到了。对于加载的 RESX 文件,您可以参考内置资源管理器。见stackoverflow.com/a/22494089/264628
  • @BrianS 感谢您的补充:)
【解决方案4】:
public static class ResourceManagerHelper
{
    public static string GetResourceName(this ResourceManager resourceManager, string value, CultureInfo cultureInfo, bool ignoreCase = false)
    {
        var comparisonType = ignoreCase ? System.StringComparison.OrdinalIgnoreCase : System.StringComparison.Ordinal;
        var entry = resourceManager.GetResourceSet(cultureInfo, true, true)
                                   .OfType<DictionaryEntry>()
                                   .FirstOrDefault(dictionaryEntry => dictionaryEntry.Value.ToString().Equals(value, comparisonType));

        if (entry.Key == null)
            throw new System.Exception("Key and value not found in the resource file");

        return entry.Key.ToString();
    }
}

调用这个扩展方法,

var key = Resources.ResourceManager.GetResourceName(value, CultureInfo.InvariantCulture, true);

在这种情况下,我们不想传递资源程序集,而是可以使用特定资源的 resourceManager 调用。

【讨论】:

  • ResourceManagerHelper 是 ResourceManager 的常用扩展。每个 Resource 文件都有 Resource Manager,例如:Rule.resx 是一个资源文件。然后拨打Rule.ResourceManager.GetResourceName(val, mycultureinfo)
【解决方案5】:

你可以使用这个内联代码(c#,ASP.NET MVC)

var _resource = new ResourceManager(typeof(/*your resource*/));
string res = _resource.GetString(/*resource key*/);

我认为这可以帮助你。

【讨论】:

  • 为什么这个答案能解决 OP 的问题?
【解决方案6】:

这是一个有限的例子:

  • 使用子文件夹中的资源文件
  • 使用与默认文化不同的文化

.

public static string GetLocalizedNameReversed(string value)
{
    ResourceManager rm = new ResourceManager($"YourNamespace.YourFolder.YourResourceFileName", assembly);

    var entry = rm.GetResourceSet(new CultureInfo("nb-NO"), true, true)
            .OfType<DictionaryEntry>()
            .FirstOrDefault(e => e.Value.ToString().Equals(value, StringComparison.OrdinalIgnoreCase));

    return entry.Key.ToString();
}

【讨论】:

    【解决方案7】:

    简单直接的方法是-

    var keyValue = Resources.ResourceManager.GetString("AboutTitle");
    

    在上面的“AboutTitle”是“KEY”部分,因此如果您在资源“AboutTitle= About”中有上述keyValue = About的结果

    我在 VS2019 中的一个项目中使用了它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多