Walkthrough: Embedding Localized Resources for a JavaScript File

This walkthrough describes how to include an ECMAScript (JavaScript) file as an embedded resource in an assembly, and how to include localized strings for use in the JavaScript file. You embed a JavaScript file in an assembly when you have a client script component that must be distributed with the assembly. The JavaScript file can be referenced from a Web application that registers the assembly. You embed localized resources when you have to modify values that are used by the JavaScript file for different languages and cultures.

Prerequisites

To implement the procedures in this walkthrough you need:

  • Visual Studio 2010 or Visual Web Developer 2010 Express, or later versions of these products.

Creating an Assembly that Contains an Embedded JavaScript File

You will begin by creating an assembly (.dll file) that contains the JavaScript file that you want to treat as a resource. You will do so by creating a class library project in Visual Studio, which creates an assembly as its output.

To embed a client script file and resources in an assembly

  1. In Visual Studio, create a new class library project named LocalizingScriptResources.

  2. Add references to the System.Web and System.Web.Extensions assemblies to the project.

  3. Add a new JScript file to the project named CheckAnswer.js.

  4. Add the following code to the CheckAnswer.js file.

    function CheckAnswer()
    {
        var firstInt = $get('firstNumber').innerText;
        var secondInt = $get('secondNumber').innerText;
        var userAnswer = $get('userAnswer');
    
        if ((Number.parseLocale(firstInt) + Number.parseLocale(secondInt)) == userAnswer.value)
        {
            alert(Answer.Correct);
            return true;
        }
        else
        {
            alert(Answer.Incorrect);
            return false;
        }
    }
    
    function CheckAnswer()
    {
        var firstInt = $get('firstNumber').innerText;
        var secondInt = $get('secondNumber').innerText;
        var userAnswer = $get('userAnswer');
    
        if ((Number.parseLocale(firstInt) + Number.parseLocale(secondInt)) == userAnswer.value)
        {
            alert(Answer.Correct);
            return true;
        }
        else
        {
            alert(Answer.Incorrect);
            return false;
        }
    }
    

    The script checks the user's result for adding two numbers. It uses the alert function to let the user know whether the answer is correct. The message displayed in the alert dialog box is read from a localized resource without a postback to the server.

    A placeholder named Answer is used in the script to identify which resource files contain the localized strings. The Answer placeholder will be defined later in this procedure.

  5. In the Properties window for CheckAnswer.js, set Build Action to Embedded Resource.

    Set script file to embedded resource

  6. Add a class to the project named ClientVerification.

  7. Replace any code in the ClientVerification class file with the following code:

    Imports System.Web.UI
    Imports System.Web.UI.WebControls
    Imports System.Resources
    
    Public Class ClientVerification
        Inherits Control
    
        Private _button As Button
        Private _firstLabel As Label
        Private _secondLabel As Label
        Private _answer As TextBox
        Private _firstInt As Int32
        Private _secondInt As Int32
    
    
        Protected Overrides Sub CreateChildControls()
            Dim random = New Random()
            _firstInt = random.Next(0, 20)
            _secondInt = random.Next(0, 20)
    
            Dim rm = New ResourceManager("LocalizingScriptResources.VerificationResources", Me.GetType().Assembly)
            Controls.Clear()
    
            _firstLabel = New Label()
            _firstLabel.ID = "firstNumber"
            _firstLabel.Text = _firstInt.ToString()
    
            _secondLabel = New Label()
            _secondLabel.ID = "secondNumber"
            _secondLabel.Text = _secondInt.ToString()
    
            _answer = New TextBox()
            _answer.ID = "userAnswer"
    
            _button = New Button()
            _button.ID = "Button"
            _button.Text = rm.GetString("Verify")
            _button.OnClientClick = "return CheckAnswer();"
    
            Controls.Add(_firstLabel)
            Controls.Add(New LiteralControl(" + "))
            Controls.Add(_secondLabel)
            Controls.Add(New LiteralControl(" = "))
            Controls.Add(_answer)
            Controls.Add(_button)
        End Sub 
    
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Resources;
    
    
    namespace LocalizingScriptResources
    {
        public class ClientVerification : Control
        {
            private Button _button;
            private Label _firstLabel;
            private Label _secondLabel;
            private TextBox _answer;
            private int _firstInt;
            private int _secondInt;
    
            protected override void CreateChildControls()
            {
                Random random = new Random();
                _firstInt = random.Next(0, 20);
                _secondInt = random.Next(0, 20);
    
                ResourceManager rm = new ResourceManager("LocalizingScriptResources.VerificationResources", this.GetType().Assembly);
                Controls.Clear();
    
                _firstLabel = new Label();
                _firstLabel.ID = "firstNumber";
                _firstLabel.Text = _firstInt.ToString();
    
                _secondLabel = new Label();
                _secondLabel.ID = "secondNumber";
                _secondLabel.Text = _secondInt.ToString();
    
                _answer = new TextBox();
                _answer.ID = "userAnswer";
    
                _button = new Button();
                _button.ID = "Button";
                _button.Text = rm.GetString("Verify");
                _button.OnClientClick = "return CheckAnswer();";
    
                Controls.Add(_firstLabel);
                Controls.Add(new LiteralControl(" + "));
                Controls.Add(_secondLabel);
                Controls.Add(new LiteralControl(" = "));
                Controls.Add(_answer);
                Controls.Add(_button);
            }
        }
    }
    

    The code creates a custom ASP.NET control. It contains two Label controls, a TextBox control, and a Button control. The code displays two randomly generated integers and provides a text box for an answer. When the button is clicked, the CheckAnswer function is called.

  8. Add a resources file to the project and name it VerificationResources.resx.

  9. Add a string resource named Correct with a value of "Yes, your answer is correct."

  10. Add a string resource named Incorrect with a value of "No, your answer is incorrect."

  11. Add a string resource named Verify with a value of "Verify Answer".

    This resource is not retrieved by using client script. Instead, it is used to set to the Text property of the Button control when the button is created.

  12. Save and close the VerificationResources.resx file.

  13. Add a resources file named VerificationResources.it.resx to the project.

    This file will contain resource strings in Italian.

  14. Add a string resource named Correct with a value of "Si, la risposta e’ corretta."

  15. Add a string resource named Incorrect with a value of "No, la risposta e’ sbagliata."

  16. Add a string resource named Verify with a value of "Verificare la risposta".

    As with the "Verify" resource that you created in English, this resource is not retrieved by using client script. Instead, it is used to set the Text property of the Button control when the button is created.

  17. Save and close the VerificationResources.it.resx file.

  18. Add the following line to the AssemblyInfo file. You can specify any name for the type name in the ScriptResourceAttribute attribute, but it must match the type name that is used in the client script. In this example, it is set to Answer.

    <Assembly: System.Web.UI.WebResource("LocalizingScriptResources.CheckAnswer.js", "application/x-javascript")> 
    <Assembly: System.Web.UI.ScriptResource("LocalizingScriptResources.CheckAnswer.js", "LocalizingScriptResources.VerificationResources", "Answer")> 
    
    [assembly: System.Web.UI.WebResource("LocalizingScriptResources.CheckAnswer.js", "application/x-javascript")]
    [assembly: System.Web.UI.ScriptResource("LocalizingScriptResources.CheckAnswer.js", "LocalizingScriptResources.VerificationResources", "Answer")]
    

    Note

    The AssemblyInfo.vb file is in the My Project node of Solution Explorer. If you do not see any files in the My Project node, in the Project menu, click Show All Files. The AssemblyInfo.cs file is in the Properties node of Solution Explorer.

    The WebResource definition must include the default namespace of the assembly and the name of the .js file. The ScriptResource definition does not include the file name extension or the localized .resx files.

  19. Build the project.

    When compilation finishes, you will have an assembly named LocalizingScriptResources.dll. The JavaScript code in the CheckAnswer.js file and the resources in the two .resx files are embedded in this assembly as resources.

    You will also have an assembly named LocalizingScriptResources.resources.dll (a satellite assembly) that contains the Italian resources for server code.

Referencing the Embedded Script and Resources

You can now use the assembly in an AJAX-enabled ASP.NET Web site. You will be able to read the .js file and the resource values in client script.

Note

Although you can create the class library project and the Web site in the same Visual Studio solution, in this walkthrough it is not assumed that you are doing this. Having the projects in separate solutions emulates how a control developer and a page developer would work separately. However, for convenience you can create both projects in the same solution and make small adjustments to procedures in the walkthrough.

To reference the embedded script and resources

  1. In Visual Studio, create a new AJAX-enabled Web site.

  2. Add a Bin folder under the Web site root.

  3. Add the LocalizingScriptResources.dll assembly from the class library project to the Bin folder.

    Note

    If you created the class library project and the Web site in the same Visual Studio solution, you can add a reference from the class library project to the Web site. For details, see How to: Add a Project Reference to a Visual Studio Web Project.

  4. Create a folder in the Bin folder and give it the name it (for Italian).

  5. Add the LocalizingScriptResources.resources.dll satellite assembly from the it folder in the LocalizingScriptResources project to the it folder in the Web site.

  6. Add a new ASP.NET Web page to the project.

  7. Replace the code in the page with the following code:

    <%@ Page Language="VB" AutoEventWireup="true" UICulture="auto" Culture="auto" %>
    <%@ Register TagPrefix="Samples" Namespace="LocalizingScriptResources" Assembly="LocalizingScriptResources" %>
    <script runat="server">
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
            If (IsPostBack) Then
                System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CreateSpecificCulture(selectLanguage.SelectedValue)
            Else
                selectLanguage.Items.FindByValue(System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName).Selected = True
            End If
        End Sub
    
        Protected Sub selectLanguage_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
            System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CreateSpecificCulture(selectLanguage.SelectedValue)
        End Sub
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="https://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Client Localization Example</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:DropDownList runat="server" AutoPostBack="true" ID="selectLanguage" OnSelectedIndexChanged="selectLanguage_SelectedIndexChanged">
                <asp:ListItem Text="English" Value="en"></asp:ListItem>
                <asp:ListItem Text="Italian" Value="it"></asp:ListItem>
            </asp:DropDownList>
            <br /><br />
            <asp:ScriptManager ID="ScriptManager1" EnableScriptLocalization="true" runat="server">
            <Scripts>
                <asp:ScriptReference Assembly="LocalizingScriptResources" Name="LocalizingScriptResources.CheckAnswer.js" />
            </Scripts>
            </asp:ScriptManager>
            <div>
            <Samples:ClientVerification ID="ClientVerification1" runat="server" ></Samples:ClientVerification>
            </div>
        </form>
    </body>
    </html>
    
    <%@ Page Language="C#" AutoEventWireup="true" UICulture="auto" Culture="auto" %>
    <%@ Register TagPrefix="Samples" Namespace="LocalizingScriptResources" Assembly="LocalizingScriptResources" %>
    <script runat="server">
    
        protected void Page_Load(object sender, EventArgs e)
        {
            if (IsPostBack)
            {
                System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CreateSpecificCulture(selectLanguage.SelectedValue);
            }
            else
            {
                selectLanguage.Items.FindByValue(System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName).Selected = true;
            }
        }
    
        protected void selectLanguage_SelectedIndexChanged(object sender, EventArgs e)
        {
            System.Threading.Thread.CurrentThread.CurrentUICulture = System.Globalization.CultureInfo.CreateSpecificCulture(selectLanguage.SelectedValue);
        }
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    <html xmlns="https://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Client Localization Example</title>
    </head>
    <body>
        <form id="form1" runat="server">
            <asp:DropDownList runat="server" AutoPostBack="true" ID="selectLanguage" OnSelectedIndexChanged="selectLanguage_SelectedIndexChanged">
                <asp:ListItem Text="English" Value="en"></asp:ListItem>
                <asp:ListItem Text="Italian" Value="it"></asp:ListItem>
            </asp:DropDownList>
            <br /><br />
            <asp:ScriptManager ID="ScriptManager1" EnableScriptLocalization="true" runat="server">
            <Scripts>
                <asp:ScriptReference Assembly="LocalizingScriptResources" Name="LocalizingScriptResources.CheckAnswer.js" />
            </Scripts>
            </asp:ScriptManager>
            <div>
            <Samples:ClientVerification runat="server" ></Samples:ClientVerification>
            </div>
        </form>
    </body>
    </html>
    

    The control that you created in the LocalizingScriptResources project is included on the page. This control displays two numbers for the user to add and a TextBox control for the user to enter an answer. It also displays a button that calls the script in the CheckAnswer function when the button is clicked. The CheckAnswer function runs in the browser and displays a localized message that states whether the answer is correct.

    You must set the EnableScriptLocalization property of the ScriptManager object to true to enable the ScriptManager control to retrieve localized resources. You must also set the culture and UI culture to "auto" to display the strings that are based on the browser's settings.

    The page contains a DropDownList control that you can use to change the language settings without changing the settings in the browser. When the SelectedIndex property of the DropDownList control changes, the CurrentUICulture property of the CurrentThread instance is set to the value that you have selected.

  8. Run the project.

    You will see an addition problem with two randomly generated numbers and a TextBox control for entering an answer. When you enter an answer and click the Verify Answer button, you see the response in a message window that tells you whether the answer is correct. By default, the response will be returned in English.

    However, if you have set Italian as your preferred language in the browser, the answer will be in Italian. You can change the language for the response by selecting a language in the DropDownList control or by changing the preferred language in the browser.

Review

This walkthrough introduced the concept of embedding a JavaScript file as a resource in an assembly and of including localized strings. The embedded script file can be referenced and accessed in a Web application that contains the assembly. The localized strings will be displayed based on the language setting in the browser or on the language provided by the user.

See Also

Tasks

Localizing Resources for Component Libraries Overview

Walkthrough: Adding Localized Resources to a JavaScript File