Using ResourceManager
Asked Answered
S

6

33

I'm trying to use the ResourceManager in a C# class, but don't know what to substitute for the basename when creating a new instance of the ResourceManager class.

I have a separate project that contains the resource files which is referenced by my project above named as the following:

  • Resources.resx
  • Resources.es-ES.resx

If I have a code snippet as follows, what should I substitute for the basename when I want to use the English or Spanish version of the resources?

ResourceManager RM = new ResourceManager(basename,Assembly.GetExecutingAssembly());

I tried the approach suggested by Tom, but am getting the infamous error

Could not find any resources appropriate for the specified culture or the neutral culture.

My solution has two projects where project YeagerTech is a web application and project YeagerTechResources contains all the resources. Project YeagerTech has a reference to YeagerTechResources.

I have the following syntax when creating my Resource Manager:

ResourceManager RM = new ResourceManager("YeagerTechResources.Resources",
    Assembly.GetExecutingAssembly());

Obviously, it's incorrect.

The resource files in the YeagerTechResources project have their BuildAction set to Embedded Resource.

The name of my resource files are: Resources.resx and Resources.es-ES.resx.

If someone can simply tell me the exact syntax to use based on my project and resource file names when instantiating the resource manager, I would greatly appreciate it...

I've done everything I can think of to resolve this and can't....

This is my last attempt to resolve it here...

ResourceManager RM = new ResourceManager("YeagerTechResources.Resources", Assembly.GetExecutingAssembly());

sb.Append(RM.GetString("RegisterThanks"));

I am getting the following error after executing the code above:

Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "YeagerTechResources.Resources.resources" was correctly embedded or linked into assembly "YeagerTech" at compile time, or that all the satellite assemblies required are loadable and fully signed.

I am able to use the resources in the HTML markup with absolutely no issues, but when coming to the C# code in the Controller, I keep on getting the above error.

Any help for the exact syntax I need based on my projects would be greatly appreciated.

Stereophotography answered 11/1, 2012 at 19:29 Comment(4)
FYI, in Visual Studio if you "Add New Item" to your project, select "Resources File", and name it "Resources.resx", then Visual Studio will auto-generate a wrapper class for the ResourceManager class in a file named "Resources.Designer.cs". You can look at that code to see how it works. Unfortunately, the wrapper class is generated as internal to the project, so you will not be able to see that wrapper class from a different project, unless you use the InternalsVisibleTo attribute.Whiffler
@Stereophotography Do you have both a language-neutral resx file (one without the language code) and a language-specific resx (for example, Resources.en-US.resx)? You need at least the language-neutral one, and specify in the project settings which language is the neutral language for your application.Isatin
Related: Access localized resource strings without creating an instance of 'ResourceManager'?Shreveport
If you switch between languages often it makes sense to load resourcemanagers for multiple languages and have them at the ready. then you can switch at the locale when the request comes in. ------------------------------------------------------- switch (locale) { case "fr-CA": return resourceManagerFr.GetString(key, CultureInfo.CreateSpecificCulture(locale)); default: return resourceManager.GetString(key, CultureInfo.CreateSpecificCulture(locale)); }Spillway
K
54

There's surprisingly simple way of reading resource by string:

ResourceNamespace.ResxFileName.ResourceManager.GetString("ResourceKey")

It's clean and elegant solution for reading resources by keys where "dot notation" cannot be used (for instance when resource key is persisted in the database).

Karakalpak answered 22/4, 2015 at 8:57 Comment(4)
Even simpler: add "using RootNamespace.Properties" to your code file (where rootnamespace is defined in your project properties) and then just do: Resources.<ResourceName>. I'm not sure if you can do localization with this, though.Affaire
What is ResourceNamespace ? Can you provide full code ?Lateen
@Lateen It's just namespace of resource file.Rationalism
In my case, I had to prefix the namespace with ::global. Otherwise, this is a great solution.Spicule
R
21

The quick and dirty way to check what string you need it to look at the generated .resources files.

Your .resources are generated in the resources projects obj/Debug directory. (if not right click on .resx file in solution explorer and hit 'Run Custom Tool' to generate the .resources files)

Navigate to this directory and have a look at the filenames. You should see a file ending in XYZ.resources. Copy that filename and remove the trailing .resources and that is the file you should be loading.

For example in my obj/Bin directory I have the file:

MyLocalisation.Properties.Resources.resources

If the resource files are in the same Class library/Application I would use the following C#

ResourceManager RM = new ResourceManager("MyLocalisation.Properties.Resources", Assembly.GetExecutingAssembly());

However, as it sounds like you are using the resources file from a separate Class library/Application you probably want

Assembly localisationAssembly = Assembly.Load("MyLocalisation");
ResourceManager RM =  new ResourceManager("MyLocalisation.Properties.Resources", localisationAssembly);
Rhee answered 9/2, 2012 at 13:43 Comment(0)
D
11

This SO answer might help in this case.
If the main project already references the resource project, then you could just explicitly work with your generated-resource class in your code, and access its ResourceManager from that. Hence, something along the lines of:

ResourceManager resMan = YeagerTechResources.Resources.ResourceManager;

// then, you could go on working with that
ResourceSet resourceSet = resMan.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
// ...
Dagoba answered 22/8, 2013 at 9:0 Comment(0)
I
4

According to the MSDN documentation here, The basename argument specifies "The root name of the resource file without its extension but including any fully qualified namespace name. For example, the root name for the resource file named "MyApplication.MyResource.en-US.resources" is "MyApplication.MyResource"."

The ResourceManager will automatically try to retrieve the values for the current UI culture. If you want to use a specific language, you'll need to set the current UI culture to the language you wish to use.

Isatin answered 11/1, 2012 at 19:55 Comment(1)
Minor correction - the ResourceManager doesn't necessarily have to be created after the current UI culture is changed.Whiffler
A
1

in priciple it's the same idea as @Landeeyos. anyhow, expanding on that response: a bit late to the party but here are my two cents:

scenario:

I have a unique case of adding some (roughly 28 text files) predefined, template files with my WPF application. So, the idea is that everytime this app is to be installed, these template, text files will be readily available for usage. anyhow, what I did was that made a seperate library to hold the files by adding a resource.resx. Then I added all those files to this resource file (if you double click a .resx file, its designer gets opened in visual studio). I had set the Access Modifier to public for all. Also, each file was marked as an embedded resource via the Build Action of each text file (you can get that by looking at its properties). let's call this bibliothek1.dll i referenced this above library (bibliothek1.dll) in another library (call it bibliothek2.dll) and then consumed this second library in mf wpf app.

actual fun:

        // embedded resource file name <i>with out extension</i>(this is vital!) 

        string fileWithoutExt = Path.GetFileNameWithoutExtension(fileName);

        // is required in the next step

        // without specifying the culture
        string wildFile = IamAResourceFile.ResourceManager.GetString(fileWithoutExt);
        Console.Write(wildFile);

        // with culture
        string culturedFile = IamAResourceFile.ResourceManager.GetString(fileWithoutExt, CultureInfo.InvariantCulture);
        Console.Write(culturedFile);

sample: checkout 'testingresourcefilesusage' @ https://github.com/Natsikap/samples.git

I hope it helps someone, some day, somewhere!

Algoid answered 24/10, 2018 at 9:11 Comment(0)
M
0

I went through a similar issue. If you consider your "YeagerTechResources.Resources", it means that your Resources.resx is at the root folder of your project.

Be careful to include the full path eg : "project\subfolder(s)\file[.resx]" to the ResourceManager constructor.

Mcmahon answered 18/4, 2016 at 9:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.