2013-05-03 12 views
11

Oto jak mój plik wygląd RESX jak:Jak zdobyć nazwy przez ciąg wartości z zasobu .NET (RESX) plik

Name   Value  Comments 
Rule_seconds seconds  seconds 
Rule_Sound  Sound  Sound 

Co chcę jest: Nazwa przez wartość ciągu, coś jak poniżej:

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

i wdrożyć go jak poniżej:

string str = GetResxNameByValue("seconds"); 

tak że str powróci Rule_seconds

Dzięki!

+0

wydaje się, że jest to możliwe tylko wtedy, gdy plik zasobów nie zapewnia powielonych wartości, w przeciwnym razie można uzyskać nieoczekiwane klucze zasobów zwrócone. tj. jeśli masz dwie Nazwy/klucze (Time_Second, Sequence_Second), oba mają wartość "second". możesz otrzymać nazwę "Time_second", gdy spodziewasz się drugiej. – cli

Odpowiedz

19

To może pracować

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; 

    } 

z jakimś dodatkowym błędem sprawdzania ..

+0

Dzięki, a co jeśli plik zasobów jest w zespole, a nie rzeczywisty plik (RESX) w projekcie? – Learner

+0

Można określić zespół, w którym zasób jest osadzony w konstruktorze ResourceManager. Ale nadal musisz znać nazwę bazy zasobów. Jeśli nie uważasz, że możesz dowiedzieć się, jakie zasoby są osadzone w zespole przy użyciu Assembly.GetMainfestResourceNames – jure

+0

@jure: Czy można zwrócić wszystkie pary wartości klucza z zasobu? –

4

można uzyskać dostęp bezpośrednio przekazując klucz:

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 ""; 
     } 

    } 
+2

Na 7 liniach kodu widzę kilka problemów, które należy rozwiązać: Najpierw 'RM.GetString (nazwa_pliku)' już zwraca ciąg znaków. Nie ma potrzeby wywoływania 'ToString()'. Po drugie, 'RM.GetString (rulename)' może zwrócić wartość null, to zasób nie zostanie znaleziony, co spowoduje podniesienie 'NullReferenceException'. Po trzecie, 'if (value! = Null && value! =" ")' Nigdy nie zostanie osiągnięte z wartością pustą z powodu 'NullReferenceException'. Wreszcie, możesz zastąpić wszystkie, jeśli 'return RM.GetString (rul ename)? string.Empty; '. – PhilDulac

+2

Nie odnosi się to do pierwotnego pytania, które jest "odwrotnością" tego, co publikujesz jako rozwiązanie.Aby uzyskać konkretną wartość, należy pobrać klucz ... –

2

wszelki wypadek może pomóc każdemu. Ten ResourceHelper jest inspirowany przez jure i Mohan 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; 
    } 
} 
+0

Wszelkie uwagi na temat odwoływania się do zasobów ciągów w projekcie odwoływanym? Wciąż próbuję odwołać się do wyjątku. – BrianS

+0

Znalazłem to. W przypadku załadowanych plików RESX można odwoływać się do wbudowanego menedżera zasobów. Zobacz http://stackoverflow.com/a/22494089/264628. – BrianS

+0

@BrianS Dzięki za suplement :) – oloopy

0
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(); 
    } 
} 

nazwać tę metodę rozszerzenia,

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

W tym przypadku, nie chcemy przekazać zespół zasobów, raczej możemy wywołać za pomocą ResourceManager przez danego zasobu.

+1

Czy możesz wyjaśnić nieco więcej, jak działa twoja odpowiedź? –

+1

ResourceManagerHelper jest wspólnym rozszerzeniem dla ResourceManager. Każdy plik zasobów ma Menedżera zasobów, na przykład: ** Rule.resx ** to plik zasobów. Następnie wywołać 'Rule.ResourceManager.GetResourceName (val, mycultureinfo)' –

0

Można użyć tego kodu inline (C#, ASP.NET MVC)

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

myślę, że to może u pomóc.

+0

Dlaczego ta odpowiedź rozwiązuje problem PO? – sjaustirni

Powiązane problemy