In some cases in our project we have to ignore current culture of application
and get resources in English.
Basically, we do it like for all languages
<label>#ModelEntities.Properties.Resource.Gender</label>
How is it possible to get in English only?
I assume we have somehow created some reference to Resource.resx ?
I have used
ResourceManager rm = new ResourceManager("Resource.Strings",
Assembly.GetAssembly(typeof(ModelEntities.Properties.Resource)));
var s = rm.GetString("Age");
But it seems like not working.
Thank you!
I found the working solution.
First of all our resource files are ending like
Resource.resx
and not like Resources.resx
And in second we have resources in a separate assembly: ModelEntities
So the working code is following
var resourceManager = new ResourceManager(typeof(ModelEntities.Properties.Resource));
var genderString = resourceManager.GetString("Gender", ci);
You can use the resource manager class click here for more info about the class
System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("en-GB");
ResourceManager resourceManager = new ResourceManager("YourResource", Assembly.GetExecutingAssembly());
string bodyResource = resourceManager.GetString("yourText", ci);
A simple way:
YorResourceName.ResourceManager.GetString("ResourceKeyName", System.Globalization.CultureInfo.GetCultureInfo("en-US"))
Folder structure:
MyApplicationSolution
/Resources
/Resource.resx
public static string GetLocalisedRes(string resourceName = "", string resourceNameKey = "")
{
string translate = string.Empty;
string baseName = "YourNameSpace.Resources." + resourceName + "";
try
{
Type resType = Type.GetType(baseName);
ResourceManager rm = new ResourceManager(baseName, resType.Assembly);
translate = rm.GetString(resourceNameKey);
}
catch {
translate = string.Empty;
}
return translate;
}
Usage
var age = GetLocalisedRes("Resource", "Age");
This working for me
Related
guys i tried this one:
current: \netcoreapp2.1\ResultPath
target : \netcoreapp2.1\ReportPath\report1
AssemblyDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
Uri currentPath = new Uri(AssemblyDirectory + "//ResultPath");
Uri targetPath = new Uri(reportsSubDir);
Uri relPath = currentPath.MakeRelativeUri(targetPath);
In result i'm getting
relPath.OriginalString = ReportPath/report1
Why is not ../ReportPath/report1 ?
And now for example:
if i have
current: \netcoreapp2.1\ResultPath\Test
target : \netcoreapp2.1\ReportPath\report1
I'm getting correct result in this way
relPath.OriginalString = ../../ReportPath/report10
Could anyone explain me why in first step i'm getting bad Relative Path, but in second good
and any idea how can i fix it, if i want to use first and second examples in my way ?
Well, if you are using .NET 5, you're in luck, since new method was included: Path.GetRelativePath(string, string)
If not, we can always dig into MS .NET Framework code:
https://referencesource.microsoft.com/#System.Workflow.ComponentModel/AuthoringOM/Design/DesignerHelpers.cs,a561eb779ce7163d
And copy implementation, which is:
static class PathHelper
{
internal static string GetRelativePath(string pathFrom, string pathTo)
{
Uri uri = new Uri(pathFrom);
string relativePath = Uri.UnescapeDataString(uri.MakeRelativeUri(new Uri(pathTo)).ToString());
relativePath = relativePath.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
if (!relativePath.Contains(Path.DirectorySeparatorChar.ToString()))
relativePath = "." + Path.DirectorySeparatorChar + relativePath;
return relativePath;
}
}
Usage then would be:
var p1 = #"C:\users\turek\source\";
var p2 = #"C:\users\turek\desktop\";
PathHelper.GetRelativePath(p1, p2);
// returns "..\\desktop\\"
Found answer added / to current Path it looks like ::
Uri currentPath = new Uri(AssemblyDirectory + "//ResultPath/");
Still need explanation :)
Is there a way to loop through all the resources in a .resx file in C#?
You should always use the resource manager and not read files directly to ensure globalization is taken into account.
using System.Collections;
using System.Globalization;
using System.Resources;
...
/* Reference to your resources class -- may be named differently in your case */
ResourceManager MyResourceClass =
new ResourceManager(typeof(Resources));
ResourceSet resourceSet =
MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
}
Blogged about it on my blog :) Short version is, to find the full names of the resources(unless you already know them):
var assembly = Assembly.GetExecutingAssembly();
foreach (var resourceName in assembly.GetManifestResourceNames())
System.Console.WriteLine(resourceName);
To use all of them for something:
foreach (var resourceName in assembly.GetManifestResourceNames())
{
using(var stream = assembly.GetManifestResourceStream(resourceName))
{
// Do something with stream
}
}
To use resources in other assemblies than the executing one, you'd just get a different assembly object by using some of the other static methods of the Assembly class. Hope it helps :)
Use ResXResourceReader Class
ResXResourceReader rsxr = new ResXResourceReader("your resource file path");
// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
The minute you add a resource .RESX file to your project, Visual Studio will create a Designer.cs with the same name, creating a a class for you with all the items of the resource as static properties. You can see all the names of the resource when you type the dot in the editor after you type the name of the resource file.
Alternatively, you can use reflection to loop through these names.
Type resourceType = Type.GetType("AssemblyName.Resource1");
PropertyInfo[] resourceProps = resourceType.GetProperties(
BindingFlags.NonPublic |
BindingFlags.Static |
BindingFlags.GetProperty);
foreach (PropertyInfo info in resourceProps)
{
string name = info.Name;
object value = info.GetValue(null, null); // object can be an image, a string whatever
// do something with name and value
}
This method is obviously only usable when the RESX file is in scope of the current assembly or project. Otherwise, use the method provided by "pulse".
The advantage of this method is that you call the actual properties that have been provided for you, taking into account any localization if you wish. However, it is rather redundant, as normally you should use the type safe direct method of calling the properties of your resources.
// Create a ResXResourceReader for the file items.resx.
ResXResourceReader rsxr = new ResXResourceReader("items.resx");
// Create an IDictionaryEnumerator to iterate through the resources.
IDictionaryEnumerator id = rsxr.GetEnumerator();
// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
//Close the reader.
rsxr.Close();
see link: microsoft example
You can use ResourceManager.GetResourceSet.
If you want to use LINQ, use resourceSet.OfType<DictionaryEntry>(). Using LINQ allows you, for example, to select resources based on their index (int) instead of key (string):
ResourceSet resourceSet = Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (var entry in resourceSet.OfType<DictionaryEntry>().Select((item, i) => new { Index = i, Key = item.Key, Value = item.Value }))
{
Console.WriteLine(#"[{0}] {1}", entry.Index, entry.Key);
}
With the nuget package System.Resources.ResourceManager (v4.3.0) the ResourceSet and ResourceManager.GetResourceSet are not available.
Using the ResourceReader, as this post suggest: "C# - Cannot getting a string from ResourceManager (from satellite assembly)"
It's still possible to read the key/values of the resource file.
System.Reflection.Assembly resourceAssembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("YourAssemblyName"));
String[] manifests = resourceAssembly.GetManifestResourceNames();
using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
{
System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();
while (dict.MoveNext())
{
String key = dict.Key as String;
String value = dict.Value as String;
}
}
Simple read loop use this code
var resx = ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, false, false);
foreach (DictionaryEntry dictionaryEntry in resx)
{
Console.WriteLine("Key: " + dictionaryEntry.Key);
Console.WriteLine("Val: " + dictionaryEntry.Value);
}
Using LINQ to SQL:
XDocument
.Load(resxFileName)
.Descendants()
.Where(_ => _.Name == "data")
.Select(_ => $"{ _.Attributes().First(a => a.Name == "name").Value} - {_.Value}");
I put my PDF into the resources folder for an MVC 5 Razor project. This is how I opened the file:
public IActionResult ViewCCACH()
{
return GetDocumentLikeThis("FORM CC");
}
private IActionResult GetDocumentLikeThis(string likeThis)
{
ResourceManager MyResourceClass = new ResourceManager(typeof(Resources));
ResourceSet resourceSet = MyResourceClass.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
//ResourceManager resourceSet = new ResourceManager("ACH AUTH FORM CC Blank.pdf", System.Reflection.Assembly.Load("App_GlobalResources"));
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
if (resourceKey.Contains(likeThis))
{
string RunningPath = AppDomain.CurrentDomain.BaseDirectory;
string FileName = string.Format("{0}Properties\\" + resourceKey + ".pdf", Path.GetFullPath(Path.Combine(RunningPath, #"..\..\..\")));
var fileStream2 = new FileStream(FileName, FileMode.Open, FileAccess.Read);
var fsResult2 = new FileStreamResult(fileStream2, "application/pdf");
return fsResult2;
}
}
return View();
}
The code in .cshtml was simple:
<a class="tablinks btn btn-primary m-2 pull-right" href="/Merchant/ViewCCACH" target="_blank">Download File</a>
How do I programmatically locate my Dropbox folder using C#?
* Registry?
* Environment Variable?
* Etc...
UPDATED SOLUTION
Dropbox now provides an info.json file as stated here: https://www.dropbox.com/en/help/4584
If you don't want to deal with parsing the JSON, you can simply use the following solution:
var infoPath = #"Dropbox\info.json";
var jsonPath = Path.Combine(Environment.GetEnvironmentVariable("LocalAppData"), infoPath);
if (!File.Exists(jsonPath)) jsonPath = Path.Combine(Environment.GetEnvironmentVariable("AppData"), infoPath);
if (!File.Exists(jsonPath)) throw new Exception("Dropbox could not be found!");
var dropboxPath = File.ReadAllText(jsonPath).Split('\"')[5].Replace(#"\\", #"\");
If you'd like to parse the JSON, you can use the JavaScripSerializer as follows:
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var dictionary = (Dictionary < string, object>) serializer.DeserializeObject(File.ReadAllText(jsonPath));
var dropboxPath = (string) ((Dictionary < string, object> )dictionary["personal"])["path"];
DEPRECATED SOLUTION:
You can read the the dropbox\host.db file. It's a Base64 file located in your AppData\Roaming path. Use this:
var dbPath = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Dropbox\\host.db");
var dbBase64Text = Convert.FromBase64String(System.IO.File.ReadAllText(dbPath));
var folderPath = System.Text.ASCIIEncoding.ASCII.GetString(dbBase64Text);
Hope it helps!
UPDATE JULY 2016: THE CODE BELOW NO LONGER WORKS DUE TO CHANGES IN THE DROPBOX CLIENT, SEE ACCEPTED ANSWER ABOVE FOR UP-TO-DATE SOLUTION
Reinaldo's answer is essentially correct but it gives some junk output before the path because there seem to be two lines in the host.db file and in this case you only want to read the second one. The following will get you just the path.
string appDataPath = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
string dbPath = System.IO.Path.Combine(appDataPath, "Dropbox\\host.db");
string[] lines = System.IO.File.ReadAllLines(dbPath);
byte[] dbBase64Text = Convert.FromBase64String(lines[1]);
string folderPath = System.Text.ASCIIEncoding.ASCII.GetString(dbBase64Text);
Console.WriteLine(folderPath);
Cleaner version based on previous answers (use var, added exists check, remove warnings):
private static string GetDropBoxPath()
{
var appDataPath = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
var dbPath = Path.Combine(appDataPath, "Dropbox\\host.db");
if (!File.Exists(dbPath))
return null;
var lines = File.ReadAllLines(dbPath);
var dbBase64Text = Convert.FromBase64String(lines[1]);
var folderPath = Encoding.UTF8.GetString(dbBase64Text);
return folderPath;
}
This seems to be the suggested solution from Dropbox: https://www.dropbox.com/help/4584?path=desktop_client_and_web_app
Dropbox has added a new helper, there is a JSON file in either %APPDATA%\Dropbox\info.json or %LOCALAPPDATA%\Dropbox\info.json.
See https://www.dropbox.com/help/4584 for more information.
public static string getDropBoxPath()
{
try
{
var appDataPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var dbPath = Path.Combine(appDataPath, "Dropbox\\host.db");
if (!File.Exists(dbPath))
{
return null;
}
else
{
var lines = File.ReadAllLines(dbPath);
var dbBase64Text = Convert.FromBase64String(lines[1]);
var folderPath = Encoding.UTF8.GetString(dbBase64Text);
return folderPath;
}
}
catch (Exception ex)
{
throw ex;
}
}
It's not stored in the registry (at least it isn't in plain text). I believe it's stored in the following location.
C:\Users\userprofile\AppData\Roaming\Dropbox
I would say it resides in the host.db or unlink.db file.
The config.db is a sqlite file. The other two are unknown (encrypted). The config.db contains a blob field only with the schema version.
The host.db method has stopped working in later versions of dropbox.
https://www.dropbox.com/en/help/4584 gives the recommended approach.
Here is the c# code I wrote to parse the json and get the dropbox folder.
// https://www.dropbox.com/en/help/4584 says info.json file is in one of two places
string filename = Environment.ExpandEnvironmentVariables( #"%LOCALAPPDATA%\Dropbox\info.json" );
if ( !File.Exists( filename ) ) filename = Environment.ExpandEnvironmentVariables( #"%APPDATA%\Dropbox\info.json" );
JavaScriptSerializer serializer = new JavaScriptSerializer();
// When deserializing a string without specifying a type you get a dictionary <string, object>
Dictionary<string, object> obj = serializer.DeserializeObject( File.ReadAllText( filename ) ) as Dictionary<string, object>;
obj = obj[ "personal" ] as Dictionary<string, object>;
string path = obj[ "path" ] as string;
return path;
I'm posting here a solution that does not use Dictionary; so many years after original answers, every time that I try to use answers from Reinaldo and Derek, I get a Could not load type 'System.Web.Util.Utf16StringValidator' from assembly 'System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=... using both LinqPad 7 (.NET 6.0.9) and VS 2022 (Net Standard 2.0),
I do not know if this error is because I'm already referencing Newtonsoft.Json in Assembly as suggested in this unaccepted answer.
Anyway, here is 2022 piece of cake way to do it:
private static string GetDropBoxPath()
{
// https://www.dropbox.com/en/help/4584 says info.json file is in one of two places
string jsonPath = Environment.ExpandEnvironmentVariables(#"%LOCALAPPDATA%\Dropbox\info.json");
if (!File.Exists(jsonPath)) jsonPath = Environment.ExpandEnvironmentVariables(#"%APPDATA%\Dropbox\info.json");
var dropbox = JsonConvert.DeserializeObject<DropboxRoot>(File.ReadAllText(jsonPath));
return dropbox.personal.path;
}
And these are the auxiliary classes:
public class DropboxRoot
{
public Personal personal { get; set; }
}
public class Personal
{
public string path { get; set; }
public long host { get; set; }
public bool is_team { get; set; }
public string subscription_type { get; set; }
}
Update:
I added the missing two variables to the repo code blush Sincere appologies about that - I was rushing out to pick up the kids and missed it when i quickly reviewed the post.
When i call the .NET framework's MakeRelativeUri(...) method and the pass in a Uri which contains a file path .. and the file path has spaces in it .. then there's a great disturbance in the Force, as if millions of voices suddenly cried out in terror, and were suddenly silenced.
Here's my repo code. Appologies for this being an MSTest repo and not something a bit nicer like NUnit or XUnit.
[TestMethod]
public void SadPanda()
{
// Arrange.
var outputPath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\___sa.bundle.#.css";
var sourcePath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
var sourcePathJussy =
#"C:\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
// Added missing 2x vars *blush*
var sourceUri = new Uri(Path.GetDirectoryName(sourcePath) + "/", UriKind.Absolute);
var outputUri = new Uri(Path.GetDirectoryName(outputPath) + "/", UriKind.Absolute);
var relativePath = "../images/home-feature-bg.png";
var resolvedSourcePath = new Uri(sourceUri + relativePath, true);
// Act.
var resolvedOutput = outputUri.MakeRelativeUri(resolvedSourcePath);
// Assert.
Assert.IsTrue(resolvedOutput.Contains("XWing")); // :~(
}
Now if you look at the output it is something evil with the real path of the location, etc.
Now if we remove the SPACES from the paths, it now works :)
[TestMethod]
public void DoubleRaindbowUnicorns()
{
// Arrange.
var outputPath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\___sa.bundle.#.css";
var sourcePath =
#"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
var sourcePathJussy =
#"C:\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
outputPath = outputPath.Replace(" ", "-");
sourcePath = sourcePath.Replace(" ", "-");
// Added missing 2x vars *blush*
var sourceUri = new Uri(Path.GetDirectoryName(sourcePath) + "/", UriKind.Absolute);
var outputUri = new Uri(Path.GetDirectoryName(outputPath) + "/", UriKind.Absolute);
var relativePath = "../images/home-feature-bg.png";
var resolvedSourcePath = new Uri(sourceUri + relativePath, true);
// Act.
var resolvedOutput = outputUri.MakeRelativeUri(resolvedSourcePath);
// Assert.
Assert.IsFalse(resolvedOutput.Contains("XWing")); // Here yee! Woot, say I!
}
the output of this image resource is ../images/home-feature-bg.png (which by fluke is the same as it's source path) .. and not the really long evil string.
Yes / no ?
Update 2:
Renamed the subject (to better reflect the answer).
You need to use the System.IO.Path.Combine() function. What's happening here is you are using a URI class which cannot contain spaces, which would require the %20 if it were a path for HTML.
I think you are misunderstanding the purpose of the MakeRelativeUri() function. It is supposed to be called on one absolute URI taking in another in order to return the relative URI which represents how to arrive at the second resource in context of the first.
Example:
var cssFileUri = new Uri(#"C:\Temp\Spaces in this path\foo.css");
var imageFileUri = new Uri(#"C:\Temp\Images\bar.png");
var relativeUri = cssFileUri.MakeRelative(imageFileUri);
// The value of relativeUri is "../Images/bar.png"
So you can see how the relativeUri value gets us to the "bar.png" file from "foo.css".
In your example you'd pass in your CSS file path and a path to the image to get the value you have in relativePath.
In order to "undo" that (find the full path of an image in relation to a given CSS file) you construct a new Uri object:
var relativeImageUri = #"..\Image Folder\bar.png";
var cssFileUri = new Uri(#"C:\Some Path\Other Folder\foo.css");
var absoluteImageUri = new Uri(cssFileUri, relativeImageUri);
// The value of absoluteImageUri is "file:///C:/Some Path/Image Folder/bar.png"
So in order to find the resolvedOutput from your sample code:
var outputPath = #"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010 Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\___sa.bundle.#.css";
var sourcePath = #"C:\Users\AAAAAAA.BBBBB\Documents\Visual Studio 2010\Projects\XWing\Code\CCCCCCCCCCC.XWing.Application.Web\content\shared\css\home.css";
var relativePath = "../images/home-feature-bg.png";
var outputUriBase = new Uri(outputPath);
var resolvedOutput = new Uri(outputUriBase, relativePath);
You can now use the resolvedOutput Uri object to access the "home-feature-bg.png" image relative to the output path.
All these handle spaces in the path without error.
The
uriInstance.MakeRelativeUri()
method seems to be corrupt. The resulting Uri will show escaped characters when called with ToString(), e.g. %20 for an empty space. Other Uri instances don't do so, not even relative ones.
I wanted to use it for creating relative paths by subtracting the root path from a full path, then store a string from it in a DB
var baseUri = new Uri("http://myserver/pics")
var fullUri = new Uri("http://myserver/pics/myself/smile a.jpg")
var madeRelativeUri = baseUri.MakeRelativeUri(fullUri)
// madeRelativeUri.ToString() = "myself/smile%20a.jpg"
var manualRelativeUri = new Uri(#"myself/smile b", UriKind.Relative)
// manualRelativeUri.ToString() = "myself/smile b.jpg" // no escape
Is there a way to loop through all the resources in a .resx file in C#?
You should always use the resource manager and not read files directly to ensure globalization is taken into account.
using System.Collections;
using System.Globalization;
using System.Resources;
...
/* Reference to your resources class -- may be named differently in your case */
ResourceManager MyResourceClass =
new ResourceManager(typeof(Resources));
ResourceSet resourceSet =
MyResourceClass.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
}
Blogged about it on my blog :) Short version is, to find the full names of the resources(unless you already know them):
var assembly = Assembly.GetExecutingAssembly();
foreach (var resourceName in assembly.GetManifestResourceNames())
System.Console.WriteLine(resourceName);
To use all of them for something:
foreach (var resourceName in assembly.GetManifestResourceNames())
{
using(var stream = assembly.GetManifestResourceStream(resourceName))
{
// Do something with stream
}
}
To use resources in other assemblies than the executing one, you'd just get a different assembly object by using some of the other static methods of the Assembly class. Hope it helps :)
Use ResXResourceReader Class
ResXResourceReader rsxr = new ResXResourceReader("your resource file path");
// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
The minute you add a resource .RESX file to your project, Visual Studio will create a Designer.cs with the same name, creating a a class for you with all the items of the resource as static properties. You can see all the names of the resource when you type the dot in the editor after you type the name of the resource file.
Alternatively, you can use reflection to loop through these names.
Type resourceType = Type.GetType("AssemblyName.Resource1");
PropertyInfo[] resourceProps = resourceType.GetProperties(
BindingFlags.NonPublic |
BindingFlags.Static |
BindingFlags.GetProperty);
foreach (PropertyInfo info in resourceProps)
{
string name = info.Name;
object value = info.GetValue(null, null); // object can be an image, a string whatever
// do something with name and value
}
This method is obviously only usable when the RESX file is in scope of the current assembly or project. Otherwise, use the method provided by "pulse".
The advantage of this method is that you call the actual properties that have been provided for you, taking into account any localization if you wish. However, it is rather redundant, as normally you should use the type safe direct method of calling the properties of your resources.
// Create a ResXResourceReader for the file items.resx.
ResXResourceReader rsxr = new ResXResourceReader("items.resx");
// Create an IDictionaryEnumerator to iterate through the resources.
IDictionaryEnumerator id = rsxr.GetEnumerator();
// Iterate through the resources and display the contents to the console.
foreach (DictionaryEntry d in rsxr)
{
Console.WriteLine(d.Key.ToString() + ":\t" + d.Value.ToString());
}
//Close the reader.
rsxr.Close();
see link: microsoft example
You can use ResourceManager.GetResourceSet.
If you want to use LINQ, use resourceSet.OfType<DictionaryEntry>(). Using LINQ allows you, for example, to select resources based on their index (int) instead of key (string):
ResourceSet resourceSet = Resources.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
foreach (var entry in resourceSet.OfType<DictionaryEntry>().Select((item, i) => new { Index = i, Key = item.Key, Value = item.Value }))
{
Console.WriteLine(#"[{0}] {1}", entry.Index, entry.Key);
}
With the nuget package System.Resources.ResourceManager (v4.3.0) the ResourceSet and ResourceManager.GetResourceSet are not available.
Using the ResourceReader, as this post suggest: "C# - Cannot getting a string from ResourceManager (from satellite assembly)"
It's still possible to read the key/values of the resource file.
System.Reflection.Assembly resourceAssembly = System.Reflection.Assembly.Load(new System.Reflection.AssemblyName("YourAssemblyName"));
String[] manifests = resourceAssembly.GetManifestResourceNames();
using (ResourceReader reader = new ResourceReader(resourceAssembly.GetManifestResourceStream(manifests[0])))
{
System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();
while (dict.MoveNext())
{
String key = dict.Key as String;
String value = dict.Value as String;
}
}
Simple read loop use this code
var resx = ResourcesName.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, false, false);
foreach (DictionaryEntry dictionaryEntry in resx)
{
Console.WriteLine("Key: " + dictionaryEntry.Key);
Console.WriteLine("Val: " + dictionaryEntry.Value);
}
Using LINQ to SQL:
XDocument
.Load(resxFileName)
.Descendants()
.Where(_ => _.Name == "data")
.Select(_ => $"{ _.Attributes().First(a => a.Name == "name").Value} - {_.Value}");
I put my PDF into the resources folder for an MVC 5 Razor project. This is how I opened the file:
public IActionResult ViewCCACH()
{
return GetDocumentLikeThis("FORM CC");
}
private IActionResult GetDocumentLikeThis(string likeThis)
{
ResourceManager MyResourceClass = new ResourceManager(typeof(Resources));
ResourceSet resourceSet = MyResourceClass.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
//ResourceManager resourceSet = new ResourceManager("ACH AUTH FORM CC Blank.pdf", System.Reflection.Assembly.Load("App_GlobalResources"));
foreach (DictionaryEntry entry in resourceSet)
{
string resourceKey = entry.Key.ToString();
object resource = entry.Value;
if (resourceKey.Contains(likeThis))
{
string RunningPath = AppDomain.CurrentDomain.BaseDirectory;
string FileName = string.Format("{0}Properties\\" + resourceKey + ".pdf", Path.GetFullPath(Path.Combine(RunningPath, #"..\..\..\")));
var fileStream2 = new FileStream(FileName, FileMode.Open, FileAccess.Read);
var fsResult2 = new FileStreamResult(fileStream2, "application/pdf");
return fsResult2;
}
}
return View();
}
The code in .cshtml was simple:
<a class="tablinks btn btn-primary m-2 pull-right" href="/Merchant/ViewCCACH" target="_blank">Download File</a>