Introduction
This is an ASP.NET control that can be dragged to a webpage or user control. It registers a JavaScript block to the page, which contains an object that represents the contents of a resx (resource) file (key and value). This is useful to get resource strings from JavaScript code (client side).
Background
It is known that getting resource strings in client-side JavaScript is not straightforward. This control makes it easy to share the same server side resource files (resx files) in client side code.
Using the Code
This web control will write all the entries in the specified resx file to a JavaScript (client side) object. So please make sure that the resx file entries don't contain sensitive data and the number of the entries in the resx file is not too large.
The code contains two classes, ResourcesToJavaScriptBase
and GlobalResourcesToJavaScript
. ResourcesToJavaScriptBase
acts as an abstract
base class that contains the logic of the idea. GlobalResourcesToJavaScript
is a concrete class that specializes the logic to handle global resources (in the App_GlobalResources folder).
Note: If the resource key contains a dot (.), it will be replaced by an underscore (_). Example: textBox1.Text
will be converted to textBox1_Text
in the JavaScript object.
ResourcesToJavaScriptBase
public abstract class ResourcesToJavaScriptBase : Control
{
protected abstract string GetResXFilePath();
public abstract string JavaScriptObjectName
{
get;
set;
}
protected abstract string GetResourceValue(string key);
protected virtual void ValidateBeforeRender(System.Web.UI.HtmlTextWriter writer)
{
if (!File.Exists(GetResXFilePath()))
{
writer.Write("GlobalResourcesToJavaScript: " + this.ClientID +
": Can't find the file " + GetResXFilePath());
return;
}
return;
}
protected override void OnLoad(EventArgs e)
{
if (!string.IsNullOrEmpty(JavaScriptObjectName) &&
File.Exists(GetResXFilePath()) &&
!Page.ClientScript.IsClientScriptBlockRegistered(
GetType(), JavaScriptObjectName))
{
StringBuilder script = new StringBuilder();
script.Append("<script type=\"text/javascript\"> ");
using (System.Resources.ResXResourceReader resourceReader =
new System.Resources.ResXResourceReader(GetResXFilePath()))
{
script.Append(" var " + JavaScriptObjectName + " = { ");
bool first = true;
foreach (DictionaryEntry entry in resourceReader)
{
if (first)
first = false;
else
script.Append(" , ");
script.Append(NormalizeVariableName(entry.Key as string));
script.Append(":");
script.Append("'" + GetResourceValue(entry.Key as string) + "'");
}
script.Append(" }; </script>");
Page.ClientScript.RegisterClientScriptBlock(GetType(),
JavaScriptObjectName, script.ToString(), false);
}
}
base.OnLoad(e);
}
protected override void Render(HtmlTextWriter writer)
{
ValidateBeforeRender(writer);
base.Render(writer);
}
protected static string NormalizeVariableName(string key)
{
return key.Replace('.', '_');
}
}
GlobalResourcesToJavaScript
public class GlobalResourcesToJavaScript : ResourcesToJavaScriptBase
{
public string GlobalResXFileName
{
get;
set;
}
private string _javaScriptObjectName;
public override string JavaScriptObjectName
{
set
{
_javaScriptObjectName = value;
}
get
{
if (!string.IsNullOrEmpty(_javaScriptObjectName) &&
_javaScriptObjectName.Trim() != string.Empty)
{
return NormalizeVariableName(_javaScriptObjectName);
}
return NormalizeVariableName(GlobalResXFileName);
}
}
protected override string GetResourceValue(string key)
{
string value = HttpContext.GetGlobalResourceObject
(GlobalResXFileName, key) as string;
return value == null ? string.Empty : value;
}
protected override string GetResXFilePath()
{
return Page.MapPath(Path.Combine("~//App_GlobalResources",
GlobalResXFileName + ".resx"));
}
protected override void ValidateBeforeRender(System.Web.UI.HtmlTextWriter writer)
{
if (string.IsNullOrEmpty(GlobalResXFileName) ||
GlobalResXFileName.Trim() == string.Empty)
{
writer.Write("GlobalResourcesToJavaScript: " +
this.ClientID + ": Please specify GlobalResXFileName");
return;
}
base.ValidateBeforeRender(writer);
}
}
All we need to do is to add an instance of GlobalResourcesToJavaScript
to a web page or user control and set the property GlobalResXFileName
to the file title of the required resx file.
We also may set the property JavaScriptObjectName
to the name we need to call the generated JavaScript object:
<ResourcesToJavaScript:GlobalResourcesToJavaScript
ID="GlobalResourceToJavaScript1" runat="server"
GlobalResXFileName="Resource1" JavaScriptObjectName="Resources">
</ResourcesToJavaScript:GlobalResourcesToJavaScript>
The generated JavaScript will be something like:
<script type="text/javascript">
var Resources = { Entry1:'Entry 1 text' , Entry2:'Entry 2 text' ,
Entry3:'Entry 3 text' };
</script>
And this can be easily used from any JavaScript code like:
alert(Resources.Entry2);
History
- 19th February, 2011: Initial post
- 20th February, 2011: Article updated
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.