随笔-313  评论-12175  文章-1 

在ASP.NET AJAX中使用应用程序服务和本地化(6):创建支持多语言的ASP.NET AJAX站点、小结

本文来自《ASP.NET AJAX程序设计 第II卷:客户端Microsoft AJAX Library相关》的第五章《应用程序服务和本地化》。

 

ASP.NET为Web应用程序为本地化/全球化功能提供了强大的支持,开发者只要创建不同的资源文件,ASP.NET即可根据用户的区域设定选择合适的资源文件,生成本地化页面后发送给浏览者。

ASP.NET AJAX也考虑了这个问题,并对客户端JavaScript文件的本地化和全球化支持有着可圈可点的表现。即使对于Ajax这种完全不同的Web应用程序开发模型,开发者也能够容易地创建出支持多语言的Web站点。

通过在不同JavaScript文件中给出应用程序所需要的本地化资源,ASP.NET AJAX的ScriptManager控件即可根据用户区域设定选择恰当的脚本文件并发送给客户端。而对于需要以.NET程序集方式重新发布的ASP.NET AJAX组件,ASP.NET AJAX也允许我们将本地化资源脚本嵌入到组件所在的程序集中,并随之一同发布。作为组件的使用者,我们根本无需手工维护众多的本地化脚本文件,就像使用普通的.NET控件一样简单。

提示:关于将本地化脚本文件嵌入到以.NET程序集方式重新发布的ASP.NET AJAX组件中,将在本书第III卷中自定义ASP.NET AJAX组件部分详细介绍。

在本节中,我们将从头开始,实现一个虽然简单,但是功能完备的支持多语言的ASP.NET AJAX示例站点,并借此示例程序演示创建支持多语言ASP.NET AJAX站点的方法。

 

5.6.1 ASP.NET页面支持多语言

ASP.NET AJAX建立在ASP.NET 2.0框架之上,因此,若想让ASP.NET AJAX站点支持多语言,那么首先就要保证ASP.NET 2.0页面启用了多语言支持。

我们可以在页面头部按照如下代码修改页面的声明,注意其中粗体部分:

<%@ Page Language="C#" UICulture="auto" Culture="auto" %>

像这样将UICulture和Culture属性设置为auto之后,该ASP.NET页面即可根据用户的区域设定自动选择最适合的本地化资源,进行后续处理并生成本地化的页面。

若是希望在整个Web站点全局范围内应用该设定,我们也可以修改web.config文件:

<system.web>
  <globalization uiCulture="auto" culture="auto" />
</system.web>

参考:ASP.NET 2.0内建了功能强大且简单易用的本地化功能支持,包括指定Web站点和Web页面的默认区域/语言设定等。若想了解更多有关ASP.NET 2.0本地化功能的设定,请参考这篇MSDN文章:《How to: Set the Culture and UI Culture for ASP.NET Web Page》(http://msdn2.microsoft.com/en-us/library/bz9tc508.aspx)。

 

5.6.2 创建支持本地化的JavaScript脚本文件

在实际项目中使用ASP.NET AJAX创建Ajax站点时,我们一般都会将JavaScript脚本部分独立成单独的文件,然后用ScriptManager控件引入到页面中。这样做可以降低页面的结构(XHTML)和行为(JavaScript)之间的耦合,带来更加清晰的开发模型。

在本节中的程序中,我们也将把示例站点中将要用的JavaScript脚本完全独立成单独的JavaScript文件。接下来我们将编写一个自定义的ASP.NET AJAX客户端控件——自然,该控件将会支持本地化功能,即能够提供多语言的界面。

在Web站点中创建一个专门存放脚本文件的目录,比如本示例程序中的Scripts\,然后在该目录中创建3个JavaScript文件,如图5-12所示。

图5-12 JavaScript脚本文件在Visual Studio的Solution Explorer中的结构

其中:

  1. LocalizableControl.js文件中定义了该控件的具体实现代码;
  2. StringContent.en-US.js文件中给出了该控件将要用到的英文字符串资源;
  3. StringContent.zh-CN.js文件中给出了该控件将要用到的中文字符串资源。

LocalizableControl.js文件的完整代码如下:

Type.registerNamespace("Dflying");
 
Dflying.LocalizableControl = function (element) {
    Dflying.LocalizableControl.initializeBase(this, [element]);
}
 
Dflying.LocalizableControl.prototype = {
    initialize: function() {
        var sb = new Sys.StringBuilder();
        
        // 控件的说明信息
        sb.append(Dflying.Resx.Introduction);
        sb.append("<br />");
        
        // 经过本地化的当前时间
        sb.append(Dflying.Resx.CurrentDateTimeLabel);
        sb.append(": ");
        sb.append((new Date()).localeFormat("F"));
        
        // 显示上述信息
        var element = this.get_element();
        element.innerHTML = sb.toString();
    }
}
Dflying.LocalizableControl.registerClass('Dflying.LocalizableControl', Sys.UI.Control);
 
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

可以看到,在这个简单的控件中,我们只是显示了一段说明信息和当前的时间而已——虽然没有什么实际用处,不过在演示本地化支持方面,已经足够了。请留意上述代码中的粗体部分,其中Dflying.Resx.Introduction和Dflying.Resx.CurrentDateTimeLabel均定义在其他两个JavaScript脚本文件中,提供经过本地化的字符串资源;而(new Date()).localeFormat("F")则用来以本地化的方式格式化当前的时间日期。

StringContent.en-US.js文件的完整代码如下,这就是一个简单的资源文件,其中提供了英文语言环境下的控件所需文本资源:

Type.registerNamespace("Dflying");
 
Dflying.Resx = {
    "Introduction"          : "This is a localizable control",
    "CurrentDateTimeLabel"  : "Now it is"
}
 
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

相应地,提供中文文本资源的StringContent.zh-CN.js文件的完整代码如下:

Type.registerNamespace("Dflying");
 
Dflying.Resx = {
    "Introduction"          : "这是一个支持本地化的控件",
    "CurrentDateTimeLabel"  : "现在的时间是"
}
 
if (typeof(Sys) !== 'undefined') Sys.Application.notifyScriptLoaded();

接下来,我们即可让ASP.NET AJAX有选择性地将最符合用户区域设定的脚本发送给客户端。

 

5.6.3 使用ScriptManager将多语言脚本文件引入到页面中

回顾前一小节中定义的这3个JavaScript文件,我们知道LocalizableControl.js是使用该控件所必需的,无论用户希望看到何种语言的界面,该脚本都是必不可少的。而作为提供本地化资源内容的StringContent.en-US.js和StringContent.zh-CN.js(若是还需要其他语言版本,则也可以继续添加相应的资源脚本文件),则只要从中挑选其一发送即可。

根据用户区域设置在StringContent.en-US.js和StringContent.zh-CN.js中挑选其一的工作是实现该示例程序的关键之处。但幸运的是,ASP.NET AJAX的ScriptManager已经为我们完成了这项艰巨的任务。只要按照如下代码声明ScriptManager即可,注意其中粗体部分(代码中同样将必备的脚本LocalizableControl.js也发送到了客户端):

<asp:ScriptManager ID="sm" EnableScriptLocalization="true" 
    EnableScriptGlobalization="true" runat="server">
    <Scripts>
        <asp:ScriptReference Path="~/Scripts/StringContent.js" 
            ResourceUICultures="zh-CN, en-US" />
        <asp:ScriptReference Path="~/Scripts/LocalizableControl.js" />
    </Scripts>
</asp:ScriptManager>

在上述代码中,我们将ScriptManager的EnableScriptLocalization属性设置为了true。然后在引用StringContent.en-US.js或StringContent.zh-CN.js时,我们采取了一种较为“特别”的声明方法:<asp:ScriptReference />标签的Path属性只提供了StringContent.js,至于中间的zh-CN或en-US,则用逗号(,)连接起来后写在了ResourceUICultures属性中。

通过这样的声明,ScriptManager即可知道StringContent.js这个脚本文件共有两个语言的版本:StringContent.en-US.js或StringContent.zh-CN.js,其构造的格式为[原脚本文件名].[区域名].js。然后在程序运行时,ScriptManager即可极具“智能”地在二者中挑选出一个,发送给客户端。

在上述代码中,我们还会注意到ScriptManager的EnableScriptGlobalization属性也被设置成了true。这样是为了让ScriptManager引入相关脚本,以保证诸如(new Date()).localeFormat("F")等ASP.NET AJAX内建的全球化功能能够正常工作。

提示:ASP.NET AJAX内建的用来支持全球化功能的脚本文件默认位于C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\MicrosoftAjaxLibrary\System.Web.Extensions\1.0.61025.0\Globalization\目录中。

此时在Visual Studio中调试该程序,根据当前浏览器中首选区域设置的不同,我们可以在Visual Studio的Script Explorer窗口(Ctrl + Alt + N键)中看到如图5-13或图5-14所示的StringContent.en-US.js或StringContent.zh-CN.js脚本文件。

图5-13 Visual Studio的Script Explorer中的StringContent.en-US.js脚本

图5-14 Visual Studio的Script Explorer中的StringContent.zh-CN.js脚本

在图5-13和图5-14中,可以看到ScriptManager始终发送了LocalizableControl.js这个JavaScript文件,而却有选择性地从StringContent.en-US.js或StringContent.zh-CN.js中挑选一个发送给客户端。这样,在客户端代码中我们即可直接使用定义在LocalizableControl.js中的客户端控件,而无需任何有关站点语言的考虑。

 

5.6.4 根据用户区域设定自动选择站点语言

这时,客户端应用程序已经具有了根据用户区域信息自动选择站点语言的能力。让我们在页面中创建一个该控件的实例测试一下。

在该ASP.NET页面中添加如下的JavaScript脚本,创建一个定义于LocalizableControl.js中的Dflying.LocalizableControl控件:

function pageLoad(sender, args) {
    $create(
        Dflying.LocalizableControl, 
        null, 
        null,
        null, 
        $get('localizableControl')
    );
}

其中localizableControl是定义在页面中的一个<div />元素,用来显示该控件的内容:

<div id="localizableControl">
</div>

这时我们打开浏览器,并将其首选语言设定为en-US(在IE中,选择Tools | Internet Options… | General | Languages…,参见图5-15)。

图5-15 在IE浏览器中设置页面的首选语言

浏览本示例程序页面,可以看到控件中的语言文字为英语。如图5-16所示。

图5-16 控件的英文界面

而若是在图5-15中将首选语言设定为zh-CN,我们会看到控件中的语言文字变成了中文。如图5-17所示。

图5-17控件的中文界面

5.6.5 让用户手工选择站点语言

作为一个设计良好、充分考虑到用户体验的多语言Web站点来说,给用户提供切换当前语言的功能就变得非常重要。ASP.NET为此提供了强大的支持,接下来我们就来为本示例程序添加该功能。

首先在页面中添加一个DropDownList控件,其中列举了当前站点提供的语言:

<asp:DropDownList ID="ddlLanguageSelector" runat="server" AutoPostBack="True"
    OnSelectedIndexChanged="ddlLanguageSelector_SelectedIndexChanged">
    <asp:ListItem Value="en-US">English</asp:ListItem>
    <asp:ListItem Value="zh-CN">中文</asp:ListItem>
</asp:DropDownList>

上面DropDownList控件的AutoPostBack属性设置为了true,表示若用户改变了DropDownList中的选中项目,页面将自动进行一次回送,执行ddlLanguageSelector_SelectedIndexChanged()事件处理函数。该事件处理函数的定义如下,其中根据DropDownList中的选中项目设置了当前线程的区域信息:

protected void ddlLanguageSelector_SelectedIndexChanged(object sender, EventArgs e)
{
    System.Threading.Thread.CurrentThread.CurrentUICulture =
        System.Globalization.CultureInfo.CreateSpecificCulture(
            ddlLanguageSelector.SelectedValue
        );
}

在Page_Load()函数中,我们也要设置DropDownList中的初始被选中项——自然是根据用户的默认区域设定:

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ListItem selectedItem = ddlLanguageSelector.Items.FindByValue(
            System.Threading.Thread.CurrentThread.CurrentUICulture.Name
        );
        selectedItem.Selected = true;
    }
}

再次运行本示例程序,用户即可在页面中根据喜好选择界面的语言了。如图5-18所示。

图5-18 用户可以选择网站的语言

麻雀虽小,五脏俱全。相信通过学习本节这个简单示例程序的开发全过程,我们都可以轻松地根据实际需要,创建出专业的、支持多语言的ASP.NET AJAX站点。

 

5.7 小结

ASP.NET AJAX允许我们开发者直接在客户端JavaScript代码中与ASP.NET 2.0的身份认证以及用户个性化应用程序服务进行交互,无须进行传统的整页回送。

作为身份认证应用程序服务的客户端代理, AuthenticationService对象负责所有与服务器端通信的具体实现。本章首先详细介绍了AuthenticationService对象,并给出了一个使用该对象以Ajax方式完成用户登录/注销功能的完整示例程序。

类似地,客户端ProfileService对象也是在JavaScript中操作ASP.NET 2.0用户个性化应用程序服务所不可缺少的重要重要组件。本章随后介绍了该对象的各个方法/属性/字段,并通过示例程序演示了以Ajax方式读序、修改并保存用户个性化属性的具体实现方法。

ASP.NET AJAX不但为访问ASP.NET 2.0应用程序服务提供了默认的支持,还允许我们根据实际项目的需要手工定制应用程序服务Web Service的具体实现方法。本章也简要介绍了这部分内容,并给出了自定义服务器端身份认证和用户个性化Web Service的原型。

除了能够与ASP.NET 2.0应用程序服务无缝结合之外,ASP.NET AJAX框架也为我们提供了强大的客户端脚本本地化功能支持。本章最后借助一个完整的示例程序,并穿插分析说明,介绍了创建支持多语言的ASP.NET AJAX客户端应用程序的详细方法。

posted on 2007-07-15 09:34 Dflying Chen 阅读(...) 评论(...) 编辑 收藏