I created an App_GlobalResources folder and added relevant resx files for the appropriate country in an ASP Net site.
I then add a key and value to the file. All displays on the site as required.
I am now trying to retrieve the value from this resx file from a class library, mainly using the below code
ResourceManager lang = new ResourceManager("Resource.en-AU", Assembly.Load("App_GlobalResources"));
string value = lang.GetString(Key);
return value;
but the code crashes (second line) with the error
Additional information: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Resource.en-AU.resources" was correctly embedded or linked into assembly "App_GlobalResources.ufgcy-ty" at compile time, or that all the satellite assemblies required are loadable and fully signed.
So i then tried
ResourceManager myManager = new ResourceManager(typeof("NOTHING AVAILABLE HERE")); // Seems like its expecting a resource file but since its a class library i cant do this
string myString = myManager.GetString("StringKey");
This leads me to believe that i need another way to retrieve the value from a country resx file in a Class Library but not seeing any examples of how to do this OR i need to move the existing resource files from the website to the Class Library and then copy over to the site everytime i make a change but i dont know if this is the correct approach?
Try like this:
ResourceManager resourceManager =
new ResourceManager("Resources.xxx", Assembly.Load("App_GlobalResources"));
string myString = resourceManager.GetString("StringKey");
where xxx is name of your resource file, without .resx extension and without culture name (in your case, name should be Resource (without .en-au).
ResourceManager will try to load specified resource file for current culture, depending on CurrentUICulture. If your server is set to English (Australian) language/regional settings/Culture, it will try to load Resource.en-au if your culture is set to, let's say, Romanian, it will try to find Resource.ro. If such file isn't found, it will fallback to default one, the one without culture name.
Alternatively, you can load resources like this:
[Resources namespace].[Resource file name].ResourceManager.GetString("StringKey")
Resources namespace is Namespace of your resource file (default Resources, but you can see real namespace in your resource file's .Designer.cs file) and resource file name is filename of .resx file, without extension or culture.
So, you can try like this:
string myString = Resources.Resource.ResourceManager.GetString("StringKey");
Related
I've found several posts across stackoverflow and the rest of the internet regarding how to load Xaml from a static file: they recommend creating a XmlReader or StreamReader pointing to a file found on the file system, but the .xaml document I would like to read from is going to be compiled with the rest of the assembly, so it won't have a meaningful file Uri. I do not want to copy this document around wherever the assembly goes. Is there a way to read from a .xaml document that has been compiled into the assembly?
I also know that I can simply read from a very long string literal inside the code itself, but I'd rather not do that - the UIElement produced from the Xaml should be easily edited, and I gain this by editing it in a Xaml file.
To illustrate what I'm hoping for, here's an example:
private void LoadUIElementFromCompiledXaml()
{
XmlReader xmlReader = new XmlReader("*Uri for .xaml document within my assembly*");
UIElement elementLoaded = (UIElement)XamlReader.Load(xmlReader);
}
I apologize in advance if the answer is blatantly obvious.
Before you can load Xaml from an assembly as an embedded resource, there is a bit of setup you must do. I'll walk you through an example, then from there you can customize it to suite your needs.
Create folder in your project. Name it XAML.
Add a XAML file to the XAML folder. Lets call it Sample.xaml.
Right-click on Sample.Xaml and choose properties. Set the value for Build Action to "Embedded Resource".
Right-click on the project and choose properties. Take note of the Default namespace value. We will use this as part of the path. For this example lets assume it is "MyNamespace.
Your code to load the Xaml resource would look something like this:
string defaultNamespace = "MyNamespace";
string folderName = "XAML";
string fileName = "Sample.xaml";
string path = String.Format("{0}.{1}.{2}", defaultNamespace, folderName, fileName);
using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
{
object root = XamlReader.Load(stream);
}
As you can see the path to the resource is made up of the default namespace of the project, the folder path to the file, and the file name. If the folder path has multiple levels use dots as folder separator in place of back slashes. For example Xaml\Subfolder would be Xaml.Subfolder.
I have two resource files : Resource.resx and Resource.fr.resx.
I want to be able to load resources in both english and french by using Assembly.LoadWithPartialName
Can I load french resources which are in .\fr\Resource.resx by using Assembly.LoadWithPartialName?
Edit 1:
I am currently using :
var resMgr = new ResourceManager("Currency.Strings", assembly);
result = resMgr.GetString("Romania", CultureInfo.GetCultureInfo("fr"));
Which will not bring anything but the neutral language translation.
Follow this MSDN article to get convenient access to embedded resources with the ResourceManager.
Basically, with the convention, Resource.resx Resource.fr.resx, you can create a ResourceManager looking at Resource and when you change the current thread's culture to 'fr' then the resource manager starts pulling the strings from the second resource.
A very simple thing, and I can't get it to work. I want to globalise my dll thus I'm using resource files + the ResourceManager.
I call the resourcemanager like this:
var p = new ResourceManager("Appname.Default", Assembly.GetExecutingAssembly());
Get the strings like this
System.Diagnostics.Debug.WriteLine(p.GetString("greeting"));
System.Diagnostics.Debug.WriteLine(p.GetString("greeting", new CultureInfo("nl")));
System.Diagnostics.Debug.WriteLine(p.GetString("greeting", new CultureInfo("nl-NL")));
System.Diagnostics.Debug.WriteLine(p.GetString("greeting", new CultureInfo("en")));
And it returns 4 times the same string. My files are called
Default.resx
Default.en.resx
Default.nl.resx
Default.nl-NL.resx
All file settings are the same, but as mentioned - only the resource in the Default file is used.
What am I overlooking here?
There are a few ways of using resource files, one of which is using .resx files. These files get localized automatically, based on the value of Thread.CurrentThread.CurrentUICulture. The default .resx file gets compiled into the assembly it is part of (for example your main executable), while the localized resources (Default.nl-NL.resx) get compiled into their own directory (based on the culture identifier, nl-NL in this case) into an assembly, called <AssemblyName>.resources.dll.
Addressing values from those resources is as easy as <ResourceName>.<KeyName>, for example Default.Greeting. To test it, you change the culture, using:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Default.Greeting);
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("nl-NL");
Console.WriteLine(Default.Greeting);
Which will output
Hello
Hallo
On program startup, the UI Culture is set to the culture of the computer it's running on, so you won't have to specify the language yourself to always present the localized resources. So, .resx files seem the way to go.
When using the ResourceManager from var p = new ResourceManager("Appname.Default", Assembly.GetExecutingAssembly());, you will have to read .resources files. If there is no (in your case) Appname.Default.resources file, the p.GetString will fail. So I guess you have created one .resources file earlier, but haven't converted the localized .resx files to .resources files.
If you want to use the ResourceManager to be able to specify the culture, you can use:
Default.ResourceManager.GetString("Greeting", new CultureInfo("en-US"));
Here's my code when retrieving the resource file.
ResourceManager resourceManager = ResourceManager.CreateFileBasedResourceManager("Resource.resx", #"c:\", null);
resourceValue = resourceManager.GetString("key1");
But I got this exception everytime I run this.
Could not find any resources
appropriate for the specified culture
(or the neutral culture) on disk.
baseName: Resources.resx
locationInfo: null fileName:
Resources.resx.resources
What's wrong in my code?
Steven is right, it's looking for a .ressources file. You need to compile your resx file with resgen : http://msdn.microsoft.com/en-us/library/ccec7sz1(v=vs.71).aspx
Some more info : the resx file is just a file that describes how to create a resources file. When you compile it (is compile the right word ?) with resgen, it takes all images, texts, etc.. and merge them in the real resource file that you can distribute and work with.
I suggest the following read, it may help : http://edndoc.esri.com/arcobjects/9.1/ArcGISDevHelp/DevelopmentEnvs/DotNet/WorkingWithResources.htm
It is looking for a different file, as mentioned on msdn, and in your exception message.
baseName
Type: System.String
The root name of the resources. For example, the root name for the
resource file named
"MyResource.en-US.resources" is
"MyResource".
Your file should be named "Resource.resources", when passing "Resource" as baseName to the method. When you want custom resources for different cultures, you should name them like "Resource.en-US.resources" where the "en-US" part is replaced by the desired ISO culture name.
I've created a custom configuration section using XSD. In order to parse the config file that follows this new schema, I load the resource (my .xsd file) with this:
public partial class MonitoringConfiguration
{
public const string ConfigXsd = "MonitoringAPI.Configuration.MonitoringConfiguration.xsd";
public const string ConfigSchema = "urn:MonitoringConfiguration-1.0";
private static XmlSchemaSet xmlSchemaSet;
static MonitoringConfiguration()
{
xmlSchemaSet = new XmlSchemaSet();
Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);
XmlReader schemaReader = XmlReader.Create(xsdStream);
xmlSchemaSet.Add(ConfigSchema, schemaReader);
}
}
By the way my resource is: MonitoringConfiguration.xsd. And the namespace of the other partial class (that represents the code behind of the .xsd file) is MonitoringAPI.Configuration.
The problem is situated here:
Stream xsdStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(ConfigXsd);
The xsdStream is null, so I guess the resource can't be found! But why?
Thank you
The name of the resource is always:
<Base namespace>.<RelativePathInProject>.<FileName>
So if your resource is located in "Resources/Xsd/", and your default project namespace is "MonitoringAPI.Configuration", the resource name is:
"MonitoringAPI.Configuration.Resources.Xsd.MonitoringConfiguration.xsd"
Also make sure the build action for your resource is set to "Embedded Resource"
Easy and correct way to get the actual name of your embedded resource:
string[] resourceNames =
Assembly.GetExecutingAssembly().GetManifestResourceNames();
Then simply check resourceNames array, and you will know for sure what to pass to GetManifestResourceStream method.
In my case,
When you try to access the file via GetManifestResourceStream(). You will get an error due to invalid path of the file, and stream will be null.
Solution:
Right click on the file which you have added in to solution and Click on Properties.
Select the Build Action as Embedded Resource. (Instead of Content - by default)
By default, visual studio does not embed xsd file therefore you must ensure "Build Action" property of xsd file is set to "Embedded Resource" to make it works
just add your resources under form1.resx -->add existing items
double click on the resources you added under Resources folder.go to properties and select "Embedded Resources" instead of none.
Then
try debugging the line:
string[] resourceNames=Assembly.GetExecutingAssembly().GetManifestResourceNames();
check the resources you added are in the array. then copy the resource name exactly from this array and try putting the name on your code..it works fine!!
You can get the Resource Stream by passing the Resource Names which is as follows below...
Get the resource name e.g..
Assembly objAssembly = Assembly.GetExecutingAssembly();
string[] strResourceNames = objAssembly.GetManifestResourceNames();
Pass the Resource Names to ...
Stream strm = objAssembly.GetManifestResourceStream(strResourceNames);
Now you have Stream you can do whatever you want...
In my case, it was something completely different:
My UWP App compiled correctly in Debug and Release configuration but GetManifestResourceStream returned Null only Release configuration.
The issue was, that in the UWP Build Configuration file (and only there) the setting "Compile with .NET Native tool chain" was enabled. After disabling, GetManifestResourceStream worked as expected.
I had an issue where I was embedding a whole heap of .xsd files in many different assemblies; everything was working (GetManifestResourceNames was returning the files I'd expect to see) except for one. The one which wasn't was called:
Something.LA.xsd
I wasn't dealing with specific cultures and the .LA bit at the end of the filename was being picked up by the compiler as this file being for the LA culture - the filename in the manifest was going in as Something.xsd (under culture LA) - hence me not being able to find it (it ended up in a satellite assembly). I dodged the issue by renaming the file - presumably it is possible to explicitly state the culture of a given embedded resource.
Actually, a quick google reveals:
How can I prevent embedded resource file culture being set based on its filename
According to this answer, you've got to do hacky things - so perhaps renaming the file wasn't so bad after all :)