|
Localizing page content is now easier than ever with ASP.net 2.0 and Visual Studio
2005. In this article a sample localization resource provide that uses a database
will be built. It works at runtime as well as in the designer to allow easy creation
of resources.
Here is a sample page that uses all three declarative methods of binding to resources,
as well a code-based method of accessing resources:
<%@ Page Language="C#" Culture="auto" UICulture="auto" %>
<script runat="server">
private void Page_Load() {
CodeBasedResourceLabel.Text = (string)HttpContext.GetGlobalResourceObject("MyGlobalStrings", "AnotherGlobalResource");
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Resource Sample Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
Explicit local resource:
<asp:Label ID="ExplicitLocalResourceLabel" runat="server" Text="<%$ Resources:ExplicitLabelResource %>"></asp:Label>
<br />
Implicit local resource:
<asp:Label ID="ImplicitLocalResourceLabel" runat="server" meta:resourceKey="ImplicitLabelResource1"></asp:Label><br />
Explicit global resource:
<asp:Label ID="ExplicitGlobalResourceLabel" runat="server" Text="<%$ Resources:MyGlobalStrings, GlobalResourceString %>"></asp:Label><br />
Code-based resource:
<asp:Label ID="CodeBasedResourceLabel" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
Download this sample page and resource files.
This sample works straight out of the box because ASP.net 2.0 ships with a standard
ResX-based provider for reading resource files from disk. Although this solution
works very well for many sites, often times the pages have to run against a pre-existing
database that already contains resources. Using a database also allows for better
maintenance and versioning of the resources. The solution to this problem is to
write a custom ASP.net resource provider.
The Access database sample you can download is admittedly quite simple. There are
several scenarios it doesn't support well and in some cases doesn't support at all.
For example, the indexing of local resources is based strictly on filename, so the
folder name is not used. The result is that if you have two files called Default.aspx
in two different folders, their resources will conflict. Another scenario that isn't
supported is a proper culture fallback mechanism. For example if the es-mx(Spanish
- Mexico) culture is not available, it does not know to fall back to just es(Spanish
- International Sort). Nevertheless these are features that could be added later
if one desired to do so.
Download the sample Access
localization resource provider.
Since the sample is relatively long (about 600 lines of code), only the key points
will be addressed.
Starting with the runtime components, the provider follows a factory model. A ResourceProviderFactoryhas
to be able to create two types of providers: local resource providers, and global
resource providers. A new local resource provider will be created for each page
that uses local resources, and a new global resource provider will be created for
each global class key that is used. The resource providers' responsibility is to
perform two basic tasks:
- Enumerate all known culture-neutral resources for the given store.
- Retrieve a culture-specific localized resources given a resource key and a CultureInfo
object.
In the sample, this is implemented in App_Code\AccessResourceProvider.cs. All the
runtime database code is located in App_Code\AccessResourceHelper.cs.
If you take the ASPX page seen at the top of this page and add the following data
to the Access database, you should get the same results as you did before:

Although the Access database can be edited manually to add new resources, Visual
Studio 2005 can also be used to pre-populate the database with culture-neutral resources.
A design-time extensibility mechanism is available to serve this purpose. Although
not available in Visual Web Developer Express, there is a Visual Studio menu item
under the Tools menu called Generate Local Resource.
This calls on the design-time resource providers and resource writers to add all
the culture-neutral resource to the localization store. In this sample, culture-specific
localized resource need to be added manually. The expectation is that eventually
someone would write custom tools to manage and version the data in the database.
The design-time components follow almost exactly the same model as the runtime.
In order to locate the design-time resource factory, the runtime factory has the
DesignTimeResourceProviderFactoryAttribute attribute on it. Similar
to the runtime factory, the design time factory has tobe able to create three types
of objects: design time local resource providers, design time global resource providers,
and design time local resource writers.
The job of the design time resource providers is the same as the job of the runtime
resource providers. This is implemented in App_Code\AccessDesignTimeResourceProvider.cs.
The design time resource writer's responsibility is to perform two basic tasks:
- Create resource keys for arbitrary objects.
- Add resource keys and values to a resource store.
Visual Studio will use the design-time readers and writers to populate the resource
store with the new culture neutral resources. It will also automatically add the
UICulture="auto" and Culture="auto" attributes
to the page directive to turn on browser culture detection. This is a particularly
useful feature since it tells ASP.net to automatically set the culture of the request
to be the user's browser setting. The user can configure this setting in Internet
Explorer by clicking on the Tools menu, then Options, and selecting the Languages
button.

To support this using the Access database, simply add additional rows to the
Localization table and set the culturename column
to the desired culture, for example es-mx for Spanish (Mexico).
The localization model in ASP.net 2.0 is already powerful straight out of the box,
and with the use of custom resource providers its power is greatly enhanced. By
abstracting away the actual storage and retrieval of resources, there is no reason
not to use ASP.net's localization system.
- Eilon
|