ASP.NET AJAX服务器基础结构中最重要的控件包括ScriptManager(脚本管理器)及ScriptManagerProxy(脚本管理器代理)。每个ASP.NET AJAX页面中只有一个ScriptManager控件的实例。如果ASP.NET页面中不包含ScriptManager控件,则无法启用任何AJAX功能。ScriptManagerProxy控件只能用在母版页环境中,用于引用内容页中的源脚本管理器。
ScriptManager控件用于管理和分发脚本资源,使客户端脚本能够使用Microsoft AJAX框架。使用下面的代码能在页面中添加脚本管理器:
< asp:ScriptManager runat ="server" ID ="ScriptManager1" />
该控件不会生成用户界面,且只在服务器端有效,不会对客户端页面增加任何额外数据。
ScriptManager控件的属性
ScriptManager控件的属性见下表:
脚本管理器是ASP.NET AJAX页面的中枢。
ScriptManager控件的方法
下表列出了ScriptManager控件的主要方法:
这里所有的静态方法都用于将某种形式的脚本或标记添加到客户端页面中。这些静态方法是定义在页面ClientScript对象中对应方法的AJAX版本。
ScriptManager控件的RegisterXXX方法与页面ClientScript对象(ClientScriptManager对象的实例)的对应方法有何区别?
ClientScriptManager和ScriptManager的注册方法用途相同的,但使用场合不同。我们仅在执行AJAX部分呈现的回发操作期间使用ScriptManager方法来添加所需的脚本代码。除呈现阶段不同外,运行库会按常规方式处理AJAX部分呈现的回发操作。在这个阶段,脚本代码会被生成并添加所有已注册的脚本。由于ScriptManager在AJAX回发期间负责标记的生成,因而ScriptManager要获得已注册的脚本才能进行添加。如果在AJAX页面中使用ClientScriptManager的方法,那么在更新面板刷新期间,可能不会添加任何脚本。
ScriptManager控件的事件
下表列出了ScriptManager控件支持的两个事件:
下面代码是ResolveScriptReference事件的使用示例,我们可以更改即将下载到客户端的脚本的路径:
protected void ResolveScript( object sender, ScriptReferenceEventArgs e)
{
if ( string .Equals(e.Script.Path, " personal.js " , StringComparison.OrdinalIgnoreCase))
{
e.Script.Path = " person.js " ;
}
}
下面是AsyncPostBackError事件的使用示例,它可以根据用户的不同IP来显示不同的错误消息:
protected void AsyncPostBackError( object sender, AsyncPostBackErrorEventArgs e)
{
ScriptManager sm = sender as ScriptManager;
if (Request.UserHostAddress == " 127.0.0.1 " )
{
sm.AsyncPostBackErrorMessage = string .Format( " <b>An error occured.<br/>{0}<b> " , e.Exception.Message);
}
else
{
sm.AsyncPostBackErrorMessage = string .Format( " <b>An error occured.<br/>{0}<b> " , " Please contace your web master. " );
}
}
如果异常在部分呈现操作执行的过程中抛出,那么HTTP请求返回的HTTP状态码为200,并提供对错误的完整描述,而不会执行标记的更新。
ScriptManagerProxy控件
我们可以将<asp:ScriptManager>标签直接添加到页面中,也可以导入已经包含脚本管理器的组件。通常,我们通过导入用户控件、为母版页创建内容页,或编写嵌套的母版页,都能调入现有脚本管理器。
如果内容页需要向管理器添加新的脚本引用,该怎么做?这种情况下,我们需要一个脚本管理器的引用。为此,我们可使用ScriptManager的GetCurrent方法来获得当前的脚本管理器实例:
sm = ScriptManager.GetCurrent( this .Page);
有了ScriptManagerProxy类,我们便不用完成这种编码工作。在需要ScriptManager控件的功能而又缺少它的引用时,可以在内容页添加ScriptManagerProxy控件。
同一个页面上下文中不能出现两个脚本管理器,但我们可引用同一个脚本管理器,并通过代理获取它。使用代理时,ScriptManager和ScriptManagerProxy控件的Scripts和Services集合会在运行时合并。
ScriptManagerProxy类是对ScriptManager类的GetCurrent方法的封装,它非常简单,能够访问的属性有限。
脚本的生成与加载
ScriptManager控件使我们能避免维护非常多的<script>标签,还能获得丰富的功能。
我们可使用Scripts集合使ScriptManager获知我们要添加到页面的脚本文件。除用户请求的脚本外,ScriptManager控件还会自动向客户端页面添加ASP.NET AJAX所需的脚本。这样,我们不必为链接Microsoft AJAX库或其他ASP.NET AJAX固有的功能而操心。下面的代码演示了这个脚本加载模型:
< asp:ScriptManager runat = " server " ID = " ScriptManager1 " >
< Scripts >
< asp:ScriptReference Name = " YourCompany.ScriptLibrary.CoolUI.js "
Assembly = " YourCompany.ScriptLib " />
< asp:ScriptReference Path = " ~/Scripts/MyLib.js " />
</ Scripts >
</ asp:ScriptManager >
下表列出了ScriptReference用于控件脚本加载的属性:
如果查看ASP.NET AJAX页面的HTML源代码,我们几乎找不到对重要脚本文件MicrosoftAjax.js的引用,而只能看到下面的代码:
< script src = " /Core35/ScriptResource.axd?d=...&t=... "
type = " text/javascript " >
</ script >
脚本的引用来自嵌入的Web资源,由HTTP处理程序ScriptResource.axd返回。在ASP.NET AJAX中,这处处理程序替代了过去与之对应的WebResource.axd处理程序--ASP.NET 2.0中内建的组件。ScriptResource.axd有何不同呢?除提供脚本引用外,ScriptResource.axd处理程序还会为请求的文件添加各种本地化的JavaScript资源。
调试版和发布版脚本文件的处理
相比传统的<script>标签,ScriptManager提供的额外服务,能按需要链接调试版或发布版的脚本文件。ASP.NET通过一种特殊的命名规范来区分调试版和发布版的脚本文件。如果发布版的脚本文件叫script.js,那么它的调试版本就是script.debug.js。
ScriptManager控件能承担具体工作,基于上述命名规范来区分这两套脚本。如果web.config文件中的<compilation>区段的debug为true,ScriptManager控件则会选取调试版的脚本。
本地化的脚本
脚本文件可拥有可本地化的元素。如果EnableScriptLocalization属性为true,同时页面合理设置了UI区域性,那么脚本管理器会自动根据当前区域性设置来获取相应的脚本文件。
本地化的执行取决于@Page指令的UICultrue属性和Page类的UICulture属性的设置:
<% @ Page Language = " C# " UICulture = " it-IT " ... %>
我们可以为每个引用的脚本指定UI区域性:
< asp:ScriptManager ID = " ScriptManager1 " runat = " server " EnableScriptLocalization = " true " >
< Scripts >
< asp:ScriptReference Path = " Person.js " ResourceUICultures = " it-IT " />
</ Scripts >
</ asp:ScriptManager >
注意,如果未指定脚本引用标签的Path属性,ResourceUICultures将被忽略。
上例中,ScriptManager对象会试图在Path指定路径下获取名为person.it-IT.js的脚本文件。
脚本的全球化
若EnableScriptGlobalization属性为true,ScriptManager会添加设置客户端全局对象Sys.CultureInfo的脚本,JavaScript类会使用它并基于区域性设置来显示内容。