I would like to know how to load string resource from another class library. Here is my structure.
Solution\
CommonLibrary\
EmbeddedResource.resx
MainGUI\
If I get the string on classes of CommonLibrary I just use EmbeddedResource.INFO_START_MSG but when I try to use typed string resource It cannot recognize the resource file. Note that the CommonLibrary is already referenced in the MainGUI.
I usually do it this way.
Solution\
CommonLibrary\
MainGUI\
EmbeddedResource.resx
But I want to use the same resource on both projects.
Add the reference to the library to the main application. Make certain that (on the Resources file) the "Access Modifier" is set to public.
Reference the string like so:
textBox1.Text = ClassLibrary1.Resource1.ClassLibrary1TestString;
I added the resource file via right clicking, thus the "1" in the name. If you go to the Properties page for the class library and click on the "Resources" tab, you can add the default resources file, which will not have the numeral "1" in the name.
Just make certain your values are public, and that you have the reference in the main project and you should have no issues.
By default the resource class is internal which means it won't be directly available in other assemblies. Try by changing it to public. A part from this you will also have to make the string properties in resource class public
The is the way I've done it in the past. However, this might not work across assemblies:
public static Stream GetStream(string resourceName, Assembly containingAssembly)
{
string fullResourceName = containingAssembly.GetName().Name + "." + resourceName;
Stream result = containingAssembly.GetManifestResourceStream(fullResourceName);
if (result == null)
{
// throw not found exception
}
return result;
}
public static string GetString(string resourceName, Assembly containingAssembly)
{
string result = String.Empty;
Stream sourceStream = GetStream(resourceName, containingAssembly);
if (sourceStream != null)
{
using (StreamReader streamReader = new StreamReader(sourceStream))
{
result = streamReader.ReadToEnd();
}
}
if (resourceName != null)
{
return result;
}
}
Related
Let's say I have a directory with a set of XML files (for example, two files called ReadMacAddress.xml and ReadManufacturerId.xml) that I need to handle each one in a special way. Basically each of these XML files are a set of commands that are being received by my class.
Suppose I have an external class that is giving commands about which file should be opened,
public static void test()
{
string RecievedCommand = "ReadMacAddress"; //Command recieved from a queue
string baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
string xml = File.ReadAllText(baseDirectory + "ReadMacAddress.xml");
}
To have the possibility of opening the file automatically based on which command is received I was thinking of doing the following, first defining an enum data structure with the names of the files and then using a switch case to differentiate between the different commands(name of the file that needs to be parsed) and then using this while parsing the file.
class My_EnumXML
{
public enum ReadXML
{
ReadMacAddress,
ReadManufacturerId,
}
}
class TestRead
{
public static void OpenFile()
{
string RecievedCommand = "ReadMacAddress";
string CurrentCommand = SMLReadInputs((My_EnumXML.ReadXML)RecievedCommand);
string xml = File.ReadAllText(baseDirectory + CurrentCommand);
}
public string SMLReadInputs(My_EnumXML.ReadXML pRecievedCommand)
{
string CurrentCommand = "";
switch (pRecievedCommand)
{
case My_EnumXML.ReadXML.ReadMacAddress:
CurrentCommand = Enum.GetName(typeof(My_EnumXML.ReadXML), 0);
case My_EnumXML.ReadXML.ReadMacAddress:
CurrentCommand = Enum.GetName(typeof(My_EnumXML.ReadXML), 0);
}
return CurrentCommand;
}
}
For this example I just used the name of two XML files but I have a 100 of these and I need to know if I am proceeding in the right way, especially since I cannot debug my code because the part about receiving commands from a message queue is being implemented by someone else.
I am using DNN 7.04.
I am trying to get a string from a resource file and have tried these:
var path1 = Localization.GetString("MyAdsPath.Text", LocalResourceFile);
var path2 = Localization.GetString("MyAdsPath.Text", LocalResourceFile + "/AdditionalInfo.ascx.resx");
path1 returns null and path2 returns the correct string from the resource file.
In both cases LocalResourcfile returns:
/desktopmodules/qEmployerCreateAd/App_LocalResources/
The problem is I don't want to hard code the resource file name as it will change when the language changes.
I think the issue is to do with the control being dynamically loaded.
Do I have to check the culture and then hard code the resource file name? Or is there a better solution?
thanks
Norb
My solution to this can be found in DNNSimpleArticle
But basically when loading the dynamic control, you just need to pass along the module configuration from the parent to it.
try
{
var controlToLoad = "Controls/ArticleList.ascx";
if (ArticleId > 0)
controlToLoad = "Controls/ArticleView.ascx";
var mbl = (dnnsimplearticleModuleBase)LoadControl(controlToLoad);
mbl.ModuleConfiguration = ModuleConfiguration;
mbl.ID = System.IO.Path.GetFileNameWithoutExtension(controlToLoad);
phViewControl.Controls.Add(mbl);
}
catch (Exception exc) //Module failed to load
{
Exceptions.ProcessModuleLoadException(this, exc);
}
I found a solution that works:
http://weblogs.asp.net/anasghanem/fixing-dotnetnuke-localization-for-child-and-dynamically-loaded-usercontrols
In case that link dies here is the solution:
Create a base UserCotrol class that inherits from PortalModuleBase and fix the LocalResourceFile like below :
public partial class BaseUserControl : DotNetNuke.Entities.Modules.PortalModuleBase
{
// basicly this will fix the localization issue
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
string FileName = System.IO.Path.GetFileNameWithoutExtension(this.AppRelativeVirtualPath);
if (this.ID != null)
//this will fix it when its placed as a ChildUserControl
this.LocalResourceFile = this.LocalResourceFile.Replace(this.ID, FileName);
else
// this will fix it when its dynamically loaded using LoadControl method
this.LocalResourceFile = this.LocalResourceFile + FileName + ".ascx.resx";
}
}
I am trying the multi language features in an application. I have created the resource files GlobalTexts.en-EN.resx GlobalTexts.fr-FR.resx and a class that sets the culture and returns the texts like (I will not go in all the details, just show the structure):
public class Multilanguage
{
...
_res_man_global = new ResourceManager("GlobalResources.Resources.GlobalTexts", System.Reflection.Assembly.GetExecutingAssembly());
...
public virtual string GetText(string _key)
{
return = _res_man_global.GetString(_key, _culture);
}
}
...
Multilanguage _translations = new Multilanguage();
...
someText = _translations.GetText(_someKey);
...
This works just fine.
Now, I would like to use this application in another solution that basically extends it (more windows etc.) which also has resource files ExtendedTexts.en-En.resx ExtendedTexts.fr-FR.resx and a new class like:
public class ExtendedMultilanguage : Multilanguage
{
...
_res_man_local = new ResourceManager("ExtendedResources.Resources.ExtendedTexts", System.Reflection.Assembly.GetExecutingAssembly());
...
public override string GetText(string _key)
{
string _result;
try
{
_result = _res_man_local.GetString(_key, _culture);
}
catch (Exception ex)
{
_result = base.GetText(_key);
}
}
...
ExtendedMultilanguage _translations = new Multilanguage();
...
someText = _translations.GetText(_someKey);
...
the idea being that if the key is not found in ExtendedTexts the method will call the base class which is looking into GlobalTexts. I did this in order to use the call GetText(wantedKey) everywhere in the code without having to care about the location of the resource (I do not want to include the translations from the extensions in the GlobalTexts files); it is juts the used class that is different from project to project.
The problem I am facing is that the try/catch is very slow when exceptions raise- I wait seconds for one window to populate. I tested with direct call and works much faster, but then I need to care all the time where the resource is located...
The question is: is there an alternative way of doing this (having resources spread in various files and have only one method that gives the desired resource without throwing an error)?
In the end I took a workaround solution and loaded all the content of the resource files in dictionaries. This way I can use ContainsKey and see if the key exists or not.
I have an application that manage IIS Application instances so I am looking for a kind of GIUD to identify each applications. This GUID must be created when the application is deployed in IIS and must be persistent to IIS/Windows updates/restarts.
I did not need the use of Microsoft.Web.Administration: I want a simple way, for each IIS application, it returns its unique ID (by a method called within it).
Here is an example of what I'm looking for and I'd like to have an unique id returned by this.????? :
public class MvcApplication : System.Web.HttpApplication
{
string myUniqueID {
get { return this.?????; }
}
}
Thanks for help.
HostingEnvironment.ApplicationID
https://msdn.microsoft.com/en-us/library/system.web.hosting.hostingenvironment.applicationid(v=vs.110).aspx
I had to do something similar.
Read the web.config file for a HostId setting. Preferably split your configuration file into two, with one config file that is local to the install, and doesn't get replaced upon upgrading to a new version of the website.
If the HostId value doesn't exist in the web.config, call Guid.NewGuid() to generate a new value.
Save the new value to the web config, preferably in the local section/file.
Return the value.
Here is some psuedo-code:
public Guid HostId
{
get
{
var result = GetSetting(ConfigFileLocalSettingList.HostId).TryToGuid();
if (result == null)
{
result = Guid.NewGuid();
SetSetting(ConfigFileLocalSettingList.HostId, result.ToString());
Save();
}
return result.Value;
}
}
You can use the assembly GUID for this purpose: In AssemblyInfo.cs, you can find
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("307E39B9-2C41-40CF-B29F-84C8BBCD6519")]
To read this value, you can use:
public static string AssemblyGUID
{
get {
var assembly = Assembly.GetExecutingAssembly();
var attribute = (System.Runtime.InteropServices.GuidAttribute)assembly.GetCustomAttributes(typeof(System.Runtime.InteropServices.GuidAttribute), true)[0];
var GUID = attribute.Value;
return GUID;
}
}
which is taken from another SO answer (you can find it here).
And if it is required, Visual Studio allows you to create a new GUID via menu Tools -> Create GUID - if you need a different one.
Or in C# you simply use
var newGuid=(Guid.NewGuid()).ToString();
Console.WriteLine(newGuid);
to create a new GUID.
how to access a text file based on its prefix
var str = GrvGeneral.Properties.Resources.ResourceManager.GetString(configFile + "_Nlog_Config");
var str1 = GrvGeneral.Properties.Resources.ResourceManager.GetObject(configFile + "_Nlog_Config");
where the configfile is the prefix of the resourcefile A & B .
Based on the configfile contents (prefix) the resource file A & B has to be accessed .
Use the DirectoryInfo class (documentation). Then you can call the GetFiles with a search pattern.
string searchPattern = "abc*.*"; // This would be for you to construct your prefix
DirectoryInfo di = new DirectoryInfo(#"C:\Path\To\Your\Dir");
FileInfo[] files = di.GetFiles(searchPattern);
Edit: If you have a way of constructing the actual file name you're looking for, you can go directly to the FileInfo class, otherwise you'll have to iterate through the matching files in my previous example.
Your question is rather vague...but it sounds like you want to get the text contents of an embedded resource. Usually you would do that using Assembly.GetManifestResourceStream. You can always use LINQ along with Assembly.GetManifestResourceNames() to find the name of an embedded file matching a pattern.
The ResourceManager class is more often used for automatically retrieving localized string resources, such as labels and error messages in different languages.
update: A more generalized example:
internal static class RsrcUtil {
private static Assembly _thisAssembly;
private static Assembly thisAssembly {
get {
if (_thisAssembly == null) { _thisAssembly = typeof(RsrcUtil).Assembly; }
return _thisAssembly;
}
}
internal static string GetNlogConfig(string prefix) {
return GetResourceText(#"Some\Folder\" + prefix + ".nlog.config");
}
internal static string FindResource(string pattern) {
return thisAssembly.GetManifestResourceNames()
.FirstOrDefault(x => Regex.IsMatch(x, pattern));
}
internal static string GetResourceText(string resourceName) {
string result = string.Empty;
if (thisAssembly.GetManifestResourceInfo(resourceName) != null) {
using (Stream stream = thisAssembly.GetManifestResourceStream(resourceName)) {
result = new StreamReader(stream).ReadToEnd();
}
}
return result;
}
}
Using the example:
string aconfig = RsrcUtil.GetNlogConfig("a");
string bconfigname = RsrcUtil.FindResource(#"b\.\w+\.config$");
string bconfig = RsrcUtil.GetResourceText(bconfigname);