Localizing Resources for Component Libraries Overview

Localization is the process of customizing an application for a specific language and culture. The AJAX functionality in ASP.NET supports the following localization models for working with client script:

  • The .NET Framework resources model, with expanded support for localized resources that are associated with your ECMAScript (JavaScript) components. In this model, you embed script files and localized script resources in a hub-and-spoke organization of assemblies (that is, you use satellite assemblies). You can then selectively use these embedded client scripts and resources for specific languages and regions. This model enables a single code base to support multiple cultures. 

  • Static (standalone) JavaScript files on disk. In this model, localized files are grouped in a single directory as .js files instead of embedded in an assembly.

  • Updating scripts and script resources that are embedded in an assembly by using static JavaScript files. This model enables you to provide additional localization support for embedded scripts and for embedded resources without requiring any changes to the original assembly.

This topic contains the following information:

  • Scenarios

  • Background

  • Localizing Client Scripts and Script Resources in Assemblies

  • Localizing Static Script Files and Their Resources

  • Using ScriptManager to Manage Scripts in a Central Location

  • Code Examples

  • Class Reference

Scenarios

AJAX features in ASP.NET help client localization for both page developers and component developers. Page developers typically localize the following:

  • Exception messages that are generated from ASP.NET AJAX or from component libraries, based on the browser’s language setting.

  • UI for controls, such as strings for the Text property of a Button control.

  • Values for public properties of ASP.NET AJAX server controls.

  • Values for properties of client script objects and components, such as non-visual components, behaviors, and controls.

Component developers typically use localization features for the following:

  • Localizing resources that are referenced in code in JavaScript libraries (.js files). The localized resources can be deployed in separate installations, without rebuilding the main assembly or the script library.

  • Exposing localizable properties of server controls that are mapped to properties of client objects.

Background

AJAX functionality in ASP.NET builds on the ASP.NET 2.0 localization model. It provides additional support for localized script files that are embedded in an assembly or are static .js files on disk.

If you are not familiar with the ASP.NET localization model, you can find information about it in the following topics:

Localizing Client Script Files and Script Resources in Assemblies

ASP.NET AJAX functionality takes advantage of the .NET Framework resources model for localization. This model uses a hub-and-spoke arrangement to package and deploy localized resources that can be incrementally updated. The hub is the main assembly that contains the non-localized executable code. It includes both .NET Framework server code and any JavaScript code in .js files that are embedded as a resource in the assembly.

The main assembly can also contain the resources for a single culture, which is referred to as the neutral or default culture. The neutral culture is the fallback culture for the application. It is used if no culture is specified or if there are no resources for the specified culture.

Localized resources for a culture are typically created as name/value pairs in .resx files. (These .resx files can be compiled into .resources files.) The name provides access to the information in code, and the value is the localized (translated) term, image, or other element for that name. When an assembly is built, a type is generated for the .resx file in which the names are exposed as fields that provide programmatic access to the values. (You specify the name of this generated type as part of the assembly properties, as described later.)

In the hub-and-spoke model, each spoke connects to a satellite assembly that contains the resources for a single culture. The satellite assembly does not contain any code that is executed by the server. It contains only the generated type that provides programmatic access to the resource values for that culture.

This model offers the following features:

  • You can add resources for new cultures by deploying new satellite assemblies after you have already deployed an assembly. Developing culture-specific resources can require extra time. This model therefore enables you to release your main application first, and deliver additional culture-specific resources later.

  • You can update an application's satellite assemblies without recompiling your main assembly.

  • An application has to load only the satellite assembly for a particular culture, instead of unloading and reloading the main assembly. This can significantly reduce the use of system resources.

For information about how to create resource files for ASP.NET, see How to: Create Resource Files for ASP.NET Web Sites and Localizing ASP.NET Web Pages By Using Resources.

For information about how to use the .NET Framework resource-file generator (Resgen.exe) tool, see Resgen.exe (Resource File Generator). This tool converts .resx or .txt files to binary .resources files that can be linked into assemblies.

Organizing Localized Main and Satellite Assemblies

You can use the hub-and-spoke model when you want to localize an application that includes JavaScript (.js) files. In general, you organize the assembly as you would any ASP.NET application that is localized.

To manage the JavaScript files for an AJAX-enabled ASP.NET Web application, you write JavaScript code so that it does not hard-code strings or other elements that should be localized. Instead, in any place where the JavaScript code must use localized values, you get a field from the type that is generated out of the resource file.

The main assembly typically includes the following elements:

  • The JavaScript files that perform the application tasks, and that are written to use localized resources instead of hard-coded ones. The assembly can optionally include debug versions of these JavaScript files.

  • Optionally, the resources (.resx or .resources file) for a single neutral culture, which acts as the fallback culture for the application.

  • Optionally, any debug versions of neutral-culture resources. The debug version of a resource file includes any extra name/value pairs that are required for the debug versions of the JavaScript files.

A satellite assembly typically includes localized resources for a single culture for the ASP.NET application. (No satellite assembly is required for the fallback culture.) The resources for a single culture are created in a separate resource file (.resx or .resources file) and then compiled into a single satellite assembly.

Note

ASP.NET enables you to create a custom UI culture and a custom culture name. However, typically culture names are based on an ISO language code that consists of two letters for a language and two uppercase letters for a country or region. Examples include es-MX (Spanish, Mexico), es-CO (Spanish, Columbia), and fr-CA (French, Canada). For a complete list of culture names, see the System.Globalization.CultureInfo class overview.

Names for Localized Embedded Script Files

The following naming convention is recommended for localized script files that are embedded as resources:

scriptname_noextension.[debug].[UI culture identifier].[resources|resx]

The debug version of a file name includes ".debug" in the name. The release version does not.

The following table shows examples of this naming convention. The examples show a release and debug version of an embedded script file. They also show the associated release and debug versions of resources for those script files.

  • Sample.js
    A release version of a neutral-culture script file, which is embedded in the main assembly.

  • Sample.debug.js
    A debug version of a neutral-culture script file, which is also embedded in the main assembly.

  • Sample.fr-FR.resources
    A release version of resources that are associated with the script file Sample.js, localized for a specific UI culture. These resources become part of the satellite assembly.

  • Sample.debug.fr-FR.resources
    Debug-specific resources associated with the script file Sample.debug.js, localized for a specific UI culture. These resources become part of the satellite assembly that also includes the Sample.fr-FR.resources file.

This naming convention is not strictly required for script files that are embedded in assemblies or for resource files. This is because the mapping between the type generated for the resource and the resource name is accomplished by using an assembly attribute.

Localizing Debug Script Resources

If you are working in debug mode, at run time ASP.NET combines the release version of resources for script files with any additional debug resources. It then sends the resulting combination to the browser. Therefore, when you create resource files for debug versions of scripts, you have to define only the name/value pairs that are not already included in the release script resource files. By convention, debug versions of scripts and of script resources use the same name as their release counterpart but include ".debug" after the script file name.

Specifying Assembly Attributes for Localized Scripts and Localized Resources Associated with Scripts

To specify how resource files are managed when an assembly is built, you include attributes in the AssemblyInfo file (AssemblyInfo.vb or AssemblyInfo.cs file).

Note

In Visual Studio, for projects written in Visual Basic, 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. For projects written in C#, the AssemblyInfo.cs file is in the Properties node of Solution Explorer.

In ASP.NET, you mark resources for the application by using the WebResourceAttribute class. To embed JavaScript files in an assembly, you use this attribute to specify the .js files as a Web resource.

To include resource files for the embedded JavaScript files, you use the ScriptResourceAttribute class. This attribute identifies text-based resources specifically as resources for the JavaScript files.

Note

The ScriptResourceAttribute class can be used to identify only text-based resources for JavaScript files. To associate a localized image (binary) file with a culture, store its URL as a localized resource that script can resolve and load.

The following example shows how to use assembly attributes to identify embedded scripts and their associated script resources.

' Indicates that neutral fallback resources are retrieved from 
' the main assembly named MainAssembly.
<assembly: NeutralResourcesLanguageAttribute("en-US",
  UltimateResourceFallbackLocation.MainAssembly)>

' Defines embedded scripts as Web resources.
<assembly:WebResource("Sample.js", "text/javascript")>
<assembly:WebResource("Sample.debug.js", "text/javascript")>

' Defines the script resources for the scripts and their types.
<assembly:ScriptResource("Sample.js", "Sample.resources", 
  "Sample.Res")>
<assembly:ScriptResource("Sample.debug.js", "Sample.debug.resources", 
  "Sample.Res")>
// Indicates that neutral fallback resources are retrieved from 
// the main assembly named MainAssembly.

[assembly: NeutralResourcesLanguageAttribute("en-US",
  UltimateResourceFallbackLocation.MainAssembly)]

// Defines embedded scripts as Web resources.
[assembly:WebResource("Sample.js", "text/javascript")]
[assembly:WebResource("Sample.debug.js", "text/javascript")]

// Defines the script resources for the scripts and their types.
[assembly:ScriptResource("Sample.js", "Sample.resources", 
  "Sample.Res")]
[assembly:ScriptResource("Sample.debug.js", "Sample.debug.resources", 
  "Sample.Res")]

In this example, a main assembly named MainAssembly contains an embedded release version of a client script file that is named Sample.js. The assembly also contains the corresponding debug version named Sample.debug.js. The .js files are identified as resources by the WebResourceAttribute attribute.

The NeutralResourcesLanguageAttribute assembly attribute is used to specify the main assembly as the fallback culture. For more information, see Neutral Resources Languages for Localization and the System.Resources.NeutralResourcesLanguageAttribute class overview.

The resources used by the script files are defined by using the ScriptResourceAttribute attribute. The Sample.resources and Sample.debug.resources files contain resource values for the Sample.js and Sample.debug.js files, respectively.

A type named Sample.Res is generated for both the release and the debug version of the script resources. This is the type that the JavaScript code uses to access localized values. For both release mode and debug mode, the build process creates only a single type. In debug mode the resources for the release version are combined with the additional resources for the debug version.

For more information about how to create assembly-information files and the assembly metadata that is required for versioned assemblies, see How to: Create Versioned Assemblies for Precompiled Web Site Projects.

Localizing Static Script Files and Their Resources

You can organize a script library as localized static script files (.js files) on disk instead of embedding the script files in assemblies. Page developers can reference the script files through the ScriptReferenceCollection class.

In the static script file model, there are no separate .resx or .resources files that can be automatically managed as resources for the JavaScript files. Instead, there are only .js files, one for every UI culture and locale combination. In effect, each .js file represents a locale-specific version of the complete JavaScript code. A typical way to manage localized script files in this model is to use the same JavaScript logic in each .js file. As in the assembly-embedded model, the JavaScript code invokes a type in order to retrieve localized resource values. The difference is that you must supply the type that contains the localized values—it is not generated for you. For example, the .js for each locale can include both the application code and a class that defines the fields that hold localized values. In each .js file, this class would contain values in a different language.

Note

In the static script file model, the application JavaScript code in .js files can get out of sync with the code in an embedded JavaScript file. This is because each script file includes a copy of the code. To avoid version-control issues with duplicated code, you can maintain a single copy of the JavaScript source files and create localized resource types in separate files. You can then generate the final combined files during your application's build process.

Localized static script files are mapped to their UI culture by including the UI culture name as part of the file name, as with embedded resources in an assembly. For example, an embedded client script file that is culturally neutral for French would be named Sample.fr.js and a culture-specific JavaScript resource for French (Canada) would be named Sample.fr-CA.js.

Localized Debug Scripts in the Static Script File Model

In the static script file model, localized resources that a script refers to are typically defined as a type in a single .js file. A debug version of a script file is organized in the same way, with both localized release resources and additional debug resources defined as a type in a single file. Debug versions of scripts use the same name as the corresponding release version, but include ".debug" after the name.

Using ScriptManager to Manage Scripts

You can use the ScriptManager control to manage static scripts that are located in a central directory on disk. To do so, put all versions of the script files in one folder, which includes release and debug versions of all localized files. The following example shows the layout of a directory structure for a static script file library:

SampleNamespace/

1.0.0.0/

Sample.js

Sample.debug.js

Sample.de-DE.js

Sample.debug.de-DE.js

Sample.fr-FR.js

Sample.debug.fr-FR.js

In this example, all the script files are in a folder that is named by using the script library version (1.0.0.0). This version-specific folder is in turn in a folder that is named after the library's namespace. Organizing a script library within folders by namespace and version can provide some version control for your library. It can also help you avoid script-name collisions between libraries. In addition, it enables consumers of your library to identify what library and library version the files belong to.

Understanding the Role of the ScriptManager Control in Localization

The ScriptManager control provides the following functionality for using localized scripts and script resources:

  • Enables you to define which UI cultures are supported, which includes custom UI cultures.

  • Interprets the culture-specific assembly attribute and automatically detects the UI culture of the browser (if any). It then reads the localized or fallback scripts and resources from the assembly. In debug mode, it tries to load a script resource that contains both the appropriate UI culture name and the string ".debug" in the file name, such as Sample.debug.fr-FR.resources.

  • Generates URLs that point to the appropriate scripts and to their localized resources. For added security, it encrypts the URLs.

  • Determines whether a script or script resource will be compressed, based on a parameter in the generated URL.

  • Adds a timestamp to the assembly that contains embedded scripts so that the browser does not indefinitely cache the scripts.

For more information, see the ScriptManager class overview.

The following example shows part of a Web page that uses the ScriptManager control to register a client control that is located in an assembly. The embedded script is registered by using the Assembly and Name properties.

<%@ Register TagPrefix="Samples" Namespace="DemoControls" 
  Assembly=" SampleAssembly" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
  <title>ScriptReference</title>
</head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:ScriptManager ID="ScriptManager1" runat="server">
        <Scripts>
          <asp:ScriptReference Assembly="SampleAssembly"
              Name="DemoControls.SampleControl.js" />
        </Scripts>
      </asp:ScriptManager>

      <!-- Additional markup here. -->

    </div>
  </form>
</body>

Code Examples

The following sections include code examples that show how to work with JavaScript files and resources.

How-to and Walkthrough Topics

Class Reference

The following table lists the key classes that are used for localizing component libraries.

  • ScriptManager
    Manages AJAX components, partial-page rendering, client requests, and server responses on ASP.NET server pages.

  • ScriptReference
    Provides APIs for registering JavaScript files for use in a Web page, either files that are embedded in an assembly or that are on disk.

  • ScriptReferenceCollection
    Provides access to ScriptReference objects that represent client script files.

See Also

Tasks

Creating Custom Non-Visual Client Components

How to: Create Resource Files for ASP.NET Web Sites

How to: Create Versioned Assemblies for Precompiled Web Site Projects

Dynamically Assigning Script References

Reference

Resgen.exe (Resource File Generator)

Concepts

ASP.NET Web Page Resources Overview

Other Resources

Localizing ASP.NET Web Pages By Using Resources