一、 简介
在ASP.NET AJAX组件开发中,存在许多环节有待我们深入挖掘。如何让ASP.NET AJAX服务端控件更有效地利用客户端脚本来为控件添加强大的客户端功能?如何更为方便地访问控件访问的资源,等等。实践证明,要实现最终的应用程序资源(如JavaScript文件、图像或资源文件)的分布,一种良好的方式就是把它们直接嵌入到编译好的.NET程序集内部。
本文中,我们将探讨ASP.NET AJAX组件开发过程的一个相关环节:如何把一个JavaScript文件作为一种嵌入式资源“隐藏”到一个程序集的内部,然后再从注册该程序集的一个Web应用程序中来引用这些资源。
【注】本文示例程序测试环境:Windows XP专业版+Visual Studio 2005+ASP.NET AJAX框架。
二、 把客户端脚本文件嵌入程序集中
(一)创建一个空类库
首先,启动Visual Studio 2005,选择“文件→新建项目…”,选择C#作为内置支持语言,然后选择“类库”模板创建一个类库,命名为“MySampleControl”,最后点击OK。
然后,右击“解决方案资源管理器”中的文件夹“引用”并点击“添加引用…”,在随后出现的“添加引用”对话框中分别把对System.Web,System.Drawing和System.Web.Extensions等命名空间的引用添加到当前工程中。
(二)创建示例JavaScript脚本文件
接下来,我们在工程中添加一个名为UpdatePanelAnimation.js的简单的JScript文件。下面展示了这个JScript脚本文件的完整代码:
BorderAnimation = function(color) { this._color = color; } BorderAnimation.prototype = { animate: function(panelElement) { var s = panelElement.style; s.borderWidth = '2px'; s.borderColor = this._color; s.borderStyle = 'solid'; window.setTimeout( function() {{ s.borderWidth = 0; }}, 500); } }
上面的代码定义了一个相当简单的JavaScript类—BorderAnimation。这个类中仅提供了一个成员函数—animate,它能够实现围绕ASP.NET AJAX服务器端UpdatePanel控件显示一个带有指定颜色的边框。
接下来,在UpdatePanelAnimation.js文件相应的属性窗口中设置其生成方式为“嵌入的资源”,如下图1所示。
图1.把脚本文件的生成方式设置为嵌入资源方式。
(三)在类库中创建一个控件类
接下来,右击工程,然后点击“添加→类…”,在随后出现的“添加新项”对话框中选择“类”模板,最终在工程中添加一个名为MyCustomControl.cs的控件类文件。
【注】此时,我们可以把随同前面类库工程一起自动生成的文件class1.cs删除。
然后,打开文件MyCustomControl.cs作进一步修改。下列代码相应于我们刚才创建的控件类的完整代码:
using System; using System.Drawing; using System.Web.UI; using System.Web; using System.Globalization; namespace MySampleControl { public class UpdatePanelAnimationWithClientResource : Control { private string _updatePanelID; private Color _borderColor; private Boolean _animate; public Color BorderColor{ get { return _borderColor; } set {_borderColor = value; } } public string UpdatePanelID { get{ return _updatePanelID; } set{_updatePanelID = value; } } public Boolean Animate { get{ return _animate; } set{_animate = value; } } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); if (Animate) { UpdatePanel updatePanel = (UpdatePanel)FindControl(UpdatePanelID); string script = String.Format( CultureInfo.InvariantCulture, @" Sys.Application.add_load(function(sender, args) {{ var {0}_borderAnimation = new BorderAnimation('{1}'); var panelElement = document.getElementById('{0}'); if (args.get_isPartialLoad()) {{ {0}_borderAnimation.animate(panelElement); }} }}) ", updatePanel.ClientID, ColorTranslator.ToHtml(BorderColor)); ScriptManager.RegisterStartupScript( this, typeof(UpdatePanelAnimationWithClientResource), ClientID, script, true); } } } }
这个控件类中提供了用于定制包围UpdatePanel控件的边界颜色的属性。此外,上面的代码还注册了将要在Web页面中使用的JavaScript代码。其中,此代码还创建了一个处理器以用于加载Sys.Application对象事件。这样以来,当实现局部页面进行更新操作时,前面脚本文件UpdatePanelAnimation.js中包含的那个animate函数即被调用。
接下来,我们还必须把下列代码行添加到程序集属性文件AssemblyInfo.cs文件中。
[assembly: System.Web.UI.WebResource("MySampleControl.UpdatePanelAnimation.js", "application/x-javascript")]
注意,这里的WebResource定义中必须包括命名空间以及该.js文件的名字。
最后,用鼠标右击上面的类库工程并选择“生成”把这个类库工程构建成一个.dll程序集文件。
当编译最终完成之时,你已经拥有了自己的一个名字为SampleControl.dll的程序集。UpdatePanelAnimation.js文件中的JavaScript代码将作为一个嵌入式资源“隐藏”到这个程序集的内部。下图2展示了使用Lutz Roeder编写的.NET Reflector观察到的程序集SampleControl.dll的信息。
图2.使用.NET Reflector分析程序集SampleControl.dll的结果。