I am creating an ASP.net application to scrub Legacy data. Part of the functionality requires
generic fields (labels and button text) to be in the native language, so I plan on using the standard localization functionality of ASP.net (I have not decided if I am going to use a drop down or automatic detection yet). The other aspect of the application
allows for different Legacy Sources to be loaded into the application into generic fields that we have identified in the database. But we want to label the fields based on the Legacy Source selected within the application. And I believe that using a customized
localization file can achive this based on what the user selects from a drop down list. Is it possible to utilize two localization resource files on a single page in an ASP.net application?
Within my application I have different labels that need to be changed based on either a Language or a Source selected. Both selections will need to be made on a particular page and they will drive labels to be populated.
When a Language is selected, I want the following objects to be updated...
Specific Description/Header Labels
Warning/Error/Validation messages/labels
Button text
<div>On the same page, after a Language is selected, a Source will be selected. I want the following objects to be updated based on a Sourceselected...</div> <div>
All Grid Header fields
Search field labels
<div>I have been reading about using localization/resource files, but I have not seen any literature about using two different non-Global resource files at the same time on the same page. Is this possible? Can I use a resource file to populate fields based
on a custom resource file name? For example: Default.aspx.CustomName.resx?</div> <div></div> <div>Thanks in advance for the input and response!</div> <div></div> <div>-JoeFletch</div> </div> <div></div> <div></div>
I'm wondering if localization / resource files are not the best option here. Would maybe caching from either an XML file or from SQL server work better?
Does caching to an arrary at page load seem reasonable? I think that is what I am going to try now. My only concern is multiple users with different Languages and Sources selected. Is the caching on the client side or the server side? I can't see it being
on the client side, then how would the aspx page be generated? If it is on the server, then does asp.net just cache specific to a user?
Where each tblLanguage.ID references to its related column in tblTranslation.
In code I have defined a Language class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using MySql.Data.MySqlClient;
using System.Web.Caching;
/// <summary>
/// Summary description for Language
/// </summary>
public class Language
{
private const string CACHE_TRANSLATIONS = "Cache_Translations";
public string LCID {get; set;}
public string sDescription { get; set; }
// We use a Dictionary instead of an ObjectList as these are faster //
public Dictionary<string, string> dicTranslations;
public Language()
{
// Add constructor logic here
// Get the users prefered Language //
LCID = (HttpContext.Current.Profile as ProfileCommon).Language;
// Determine if this particular TranslationsDictionary is already in Cache //
if (HttpContext.Current.Cache[CACHE_TRANSLATIONS + LCID] != null)
{
// Get the required TranslationsDictionary from Cache //
dicTranslations = (Dictionary<string, string>)HttpContext.Current.Cache[CACHE_TRANSLATIONS + LCID];
}
else
{
// Required TranslationsDictionary not yet in Cache //
// Initialize the Translations-Dictionary //
dicTranslations = new Dictionary<string, string>();
// Get all translations from the DataBase //
GetTranslationsFromDB(LCID);
// Insert the Dictionary into Cache //
HttpContext.Current.Cache.Insert(CACHE_TRANSLATIONS + LCID, dicTranslations, null,
DateTime.Now.AddMinutes(30),
//DateTime.Now.AddSeconds(5),
Cache.NoSlidingExpiration);
}
}
private void GetTranslationsFromDB(string sALCID)
{
StringBuilder sb = new StringBuilder();
sb.Append("SELECT * ");
sb.Append(" FROM tbltranslation");
string sSql = sb.ToString();
using (MySqlConnection conn = DBResources.SportLogConnection())
{
MySqlCommand com = new MySqlCommand(sSql, conn);
//com.Parameters.AddWithValue("@pmLCID", sALCID);
com.Connection.Open();
MySqlDataReader dr = com.ExecuteReader();
while (dr.Read())
{
string sTranslationID = dr["id"].ToString();
string sValue = (dr[sALCID] is DBNull ? "" : dr[sALCID].ToString());
// Add each translation to the dictionary //
dicTranslations.Add(sTranslationID, sValue);
}
}
}
public static List<Language> GetAllLanguages()
{
List<Language> lstLanguage = new List<Language>();
StringBuilder sb = new StringBuilder();
sb.Append("SELECT * ");
sb.Append(" FROM tbllanguage ");
sb.Append(" ORDER BY description");
string sSql = sb.ToString();
using (MySqlConnection conn = DBResources.SportLogConnection())
{
MySqlCommand com = new MySqlCommand(sSql, conn);
com.Connection.Open();
MySqlDataReader dr = com.ExecuteReader();
while (dr.Read())
{
Language lan = new Language();
lan.LCID = dr["lcid"].ToString();
lan.sDescription = dr["description"].ToString();
lstLanguage.Add(lan);
}
}
return lstLanguage;
}
public string Translation(string sATranslationID)
{
string sResult;
dicTranslations.TryGetValue(sATranslationID, out sResult);
if ( (sResult == null) || (sResult == ""))
sResult = sATranslationID;
return sResult;
}
}
Note: as you can see this class only uses 1 language/resource per user at a time. You have to change it so it will have both your Language-resource and Source-resource. (You can either make a second class for the second resource type or expand the above.)
In a page you can use this Language class as follows:
private void LoadLanguage()
{
// Create Language-object //
language = new Language();
lblDisplayLanguage.Text = language.Translation("lblDisplayLanguage.Text");
}
.
As you can see, the ID of each translation-entry in tblTranslation corresponds with the [ControlID].[PropertyID]
In the above example, each language will be available in chache after its first use and stay there for the given amount of time. So if you have only two languages, there are only two objects in cache. These two objects are available for all your users.
Hy JoeFletch,
How did my example worked out for you? Could you please ‘mark as answer’ if it was helpful?
Thanks!
Thanks! Your post was quite helpful. I guess I really struggled with how the cache worked. Combining a translation/source ID with the actually source/Language Key was what cleared it up for me. For example, 1EN relates to ID 1 in the database with a Language
Key of EN. I can also have 1NL in the cache and any user can retrieve these cached values. I did change the code quite a bit though.
Public Function GetText(ByVal ID As Integer, ByVal Key As String) As String
If Cache(ID.ToString & Key) Is Nothing Then
Cache.Insert(ID.ToString & Key, LanguageSourceTextBLL.GetTextDataByIDLangaugeSource(ID, Key), Nothing, DateTime.Now.AddMinutes(3), TimeSpan.Zero)
PageStatusLabel.Text = PageStatusLabel.Text & "<br />Pulled " & ID.ToString & Key & " from the database and placed it in the cache."
Else
PageStatusLabel.Text = PageStatusLabel.Text & "<br />Pulled " & ID.ToString & Key & " from cache."
End If
Return Cache(ID.ToString & Key)
End Function
I will be pulling out the PageStateLabel.Text entries and adding time to the cache expiration.
But I still have one problem. I can not call this function on an aspx page within an asp.net control. Examples...
This will give you the posibility to step through all lines.
That is why I use a status label, so see each step along the way. The strings are being retrieved and stored in the cache. I am just having some trouble placing the retrieval code into the asp.net controls.
Member
151 Points
146 Posts
Custom Use of Localization Functionality
Jul 31, 2011 10:05 AM|JoeFletch|LINK
I am creating an ASP.net application to scrub Legacy data. Part of the functionality requires generic fields (labels and button text) to be in the native language, so I plan on using the standard localization functionality of ASP.net (I have not decided if I am going to use a drop down or automatic detection yet). The other aspect of the application allows for different Legacy Sources to be loaded into the application into generic fields that we have identified in the database. But we want to label the fields based on the Legacy Source selected within the application. And I believe that using a customized localization file can achive this based on what the user selects from a drop down list. Is it possible to utilize two localization resource files on a single page in an ASP.net application?
-JoeFletch
Member
450 Points
144 Posts
Re: Custom Use of Localization Functionality
Aug 04, 2011 03:18 AM|wangping827123|LINK
hi JoeFletch,
What is the exact scenerio like?
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Aug 04, 2011 07:00 AM|JoeFletch|LINK
Within my application I have different labels that need to be changed based on either a Language or a Source selected. Both selections will need to be made on a particular page and they will drive labels to be populated.
When a Language is selected, I want the following objects to be updated...
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Aug 04, 2011 07:05 AM|JoeFletch|LINK
Here is a crude picture of what I want.
-JoeFletch
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Aug 26, 2011 08:18 AM|JoeFletch|LINK
I'm wondering if localization / resource files are not the best option here. Would maybe caching from either an XML file or from SQL server work better?
-JoeFletch
Member
23 Points
72 Posts
Re: Custom Use of Localization Functionality
Aug 26, 2011 12:39 PM|bas bloemink|LINK
Hi JoeFletch,
As far as I know you can not use multiple (global or non-global) resource files at the same time at the same page.
As you wrote in your last post, best seems to be caching both your resources from XML or DB. That is how we do it.
Good luck!
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Aug 26, 2011 01:43 PM|JoeFletch|LINK
Does caching to an arrary at page load seem reasonable? I think that is what I am going to try now. My only concern is multiple users with different Languages and Sources selected. Is the caching on the client side or the server side? I can't see it being on the client side, then how would the aspx page be generated? If it is on the server, then does asp.net just cache specific to a user?
-JoeFletch
Member
23 Points
72 Posts
Re: Custom Use of Localization Functionality
Aug 26, 2011 02:45 PM|bas bloemink|LINK
Hi Joe,
First about caching:
- Caching is always server-side
- All users share the same cache, there is no user-specific cache
I will try to explain how we deal with our resources.
We have two tables
- tblLanguage
- LCID, varchar
- Description, varchar
- tblTranslation
- ID, varchar
- nl-NL, varchar
- en-US, varchar
Where each tblLanguage.ID references to its related column in tblTranslation.
In code I have defined a Language class:
Note: as you can see this class only uses 1 language/resource per user at a time. You have to change it so it will have both your Language-resource and Source-resource. (You can either make a second class for the second resource type or expand the above.)
In a page you can use this Language class as follows:
.
As you can see, the ID of each translation-entry in tblTranslation corresponds with the [ControlID].[PropertyID]
In the above example, each language will be available in chache after its first use and stay there for the given amount of time. So if you have only two languages, there are only two objects in cache. These two objects are available for all your users.
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Aug 26, 2011 03:09 PM|JoeFletch|LINK
Excellent. Thanks for the detailed response and your suggestions. I will try it and get back to the thread.
-JoeFletch
Member
23 Points
72 Posts
Re: Custom Use of Localization Functionality
Sep 06, 2011 06:28 AM|bas bloemink|LINK
Hy JoeFletch,
How did my example worked out for you? Could you please ‘mark as answer’ if it was helpful?
Thanks!
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Sep 06, 2011 08:25 AM|JoeFletch|LINK
Sorry, its been a rough couple of weeks (hurricane damage, household sicknesses, etc). I hope to get to it today.
-JoeFletch
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Sep 06, 2011 03:05 PM|JoeFletch|LINK
Thanks! Your post was quite helpful. I guess I really struggled with how the cache worked. Combining a translation/source ID with the actually source/Language Key was what cleared it up for me. For example, 1EN relates to ID 1 in the database with a Language Key of EN. I can also have 1NL in the cache and any user can retrieve these cached values. I did change the code quite a bit though.
I will be pulling out the PageStateLabel.Text entries and adding time to the cache expiration.
But I still have one problem. I can not call this function on an aspx page within an asp.net control. Examples...
<asp:Label ID="Label1" runat="server" Text='<% =GetText(1,"EN") %>' ></asp:Label>
<asp:Label ID="Label1" runat="server" Text='<%# GetText(1,"EN") %>' ></asp:Label>
But the following works...
<% =GetText(1,"EN") %>
-JoeFletch
Member
23 Points
72 Posts
Re: Custom Use of Localization Functionality
Sep 06, 2011 03:58 PM|bas bloemink|LINK
Let me first say, I am not a VB guy so I do not know if all the notations are correct.
But what I do see is the following:
Every item coming from Cache is of type Object. Your method dough, returns a String.
When you retrieve an item from Cache, convert it to String first before returning it:
Something else, before adding VB code to your markup, try retrieving entries from cache in code-behind first.
This will give you the posibility to step through all lines.
Member
151 Points
146 Posts
Re: Custom Use of Localization Functionality
Sep 06, 2011 04:30 PM|JoeFletch|LINK
I have made this update. Thanks.
That is why I use a status label, so see each step along the way. The strings are being retrieved and stored in the cache. I am just having some trouble placing the retrieval code into the asp.net controls.
-JoeFletch