用ASP.NET 2.0实现AJAX风格的Web开发
列表1:ProgressBar.cs
列表2:ProgressBar.jspublic class ProgressBar : System.Web.UI.Control, System.Web.UI.ICallbackEventHandler{ private int PercentCompleted{ get { if System.Web.HttpContext.Current.Session ["PercentComplete"] == null) { System.Web.HttpContext.Current.Session ["PercentComplete"] = 1; } else { System.Web.HttpContext.Current.Session["PercentComplete"] = (int)System.Web.HttpContext.Current.Session["PercentComplete"] + 1; } return (int)System.Web.HttpContext.Current.Session["PercentComplete"]; } set { System.Web.HttpContext.Current.Session["PercentComplete"] = 1; } } public string RaiseCallbackEvent(string eventArguments) { int percent = this.PercentCompleted; if (percent > 100) { this.PercentCompleted = 1; return "completed"; } else { return percent.ToString() + "%"; } } protected override void OnPreRender(EventArgs e) { this.Page.ClientScript.ReGISterClientScriptBlock(typeof(ProgressBar), "ProgressBar", this.GetClientSideScript(), true); base.OnPreRender(e); } protected override void Render(HtmlTextWriter writer) { System.Text.StringBuilder sb = new StringBuilder(); sb.Append(@"<table id=""ProgressBarContainer"" bgcolor=""LightSteelBlue"" border=""0"" width=""400"" style=""DISPLAY:none; POSITION: absolute; Z-INDEX: 10"">"); sb.Append(@"<tr><td colspan=""3"" style=""padding:3px 2px 2px 10px"">"); sb.Append(@"<font face=""Verdana,Arial,sans-serif"" size=""2"">"); sb.Append(@"<span id=""ProgressBarLabel"">Uploading...</span>"); sb.Append(@"</font></td></tr><tr><td>"); sb.Append(@"<font size=""1""> </font></td><td bgcolor=""#999999"" width=""100%"">"); sb.Append(@"<table id=""ProgressBar"" border=""0"" width=""0"" cellspacing=""0"">"); sb.Append(@"<tr><td style=""background-image:url(progressbar.gif)""> <font size=""1""> </font></td>"); sb.Append(@"</tr></table></td>"); sb.Append(@"<td><font size=""1""> </font></td></tr>"); sb.Append(@"<tr height=""5px""><td colspan=""3""></td></tr>"); sb.Append(@"</table>"); writer.Write(sb.ToString()); base.Render(writer); } private string GetClientSideScript() { System.Reflection.Assembly dll = System.Reflection.Assembly.GetExecutingAssembly(); StreamReader reader; reader = new StreamReader(dll.GetManifestResourceStream ("ProgressBar.txt")); StringBuilder js = new StringBuilder(reader.ReadToEnd()); string fp = this.Page.ClientScript.GetCallbackEventReference (this,"","UpdateProgressBar",""); js.Replace("##InitiateCallBack##",fp); reader.Close(); return js.ToS tring(); } }
<script language="javascript"> var isCompleted=false; //这个函数初始化到服务器端的回调 function DrawProgressBar(){ ##InitiateCallBack##; if (!isCompleted) { window.setTimeout('DrawProgressBar()',200); } else { isCompleted=false; document.getElementById("ProgressBarContainer").style.display = 'none'; } } //当thecallback完成时,下列函数被调用 function UpdateProgressBar(percent){ if (percent == 'completed'){ isCompleted=true; } else{ document.getElementById("ProgressBar").width = percent; } }
通过使用在ASP.net 2.0提供的客户端回调函数,实现进度条控件是比较直接的,因为在控件和客户端之间传递的数据仅是一个简单的字符串。然而,一旦我们把其它数据类型也添加到其中,我们就遇到在JavaScript和.NET类型系统之间不匹配的问题。遗憾的是,ASP.NET 2.0中的回调函数实现对此并无多大帮助。任何想使用多种数据类型(简单类型和复杂类型)的应用程序,都要实现一种自己的定制模式。
幸好,这种限制能够通过使用一个AJAX.NET开源库来加以克服,AJAX.NET实现了一种基于代理的方式来调用服务器端函数。AJAX.NET定义了一种称为AJAXMethod的定制属性。当一个服务器端方法用AJAXMethod加以修饰时,一个基于JavaScript的客户端代理将被HttpHandler(它是AJAX.NET库的一部分)自动生成。不同于ASP.NET 2.0,它支持单个参数的字符串类型以便用于回调实现。AJAX.NET支持整数,字符串,双精度数,DateTime,DataSet等多种类型。
Bertrand Le Roy建议使用AJAX.NET来处理JavaScript和.NET类型系统之间的差别。他创建了一种称为EcmaScriptObject的服务器端控件-它基于.NET技术重新创建了JavaScript类型系统。其想法是,用.NET重新生成一种客户端对象图。当转换发生在服务器端时,这种方法显得更有意义。
即使我们有了一种类型安全的方法来调用回调函数,但是,我们还面临其它的挑战。JavaScript担当起了把AJAX应用程序的各个部分组合到一起的"胶水"的作用。当然,相应地,对JavaScript的依赖性也进一步增加。遗憾的是,尽管JavaScript是一种强有力且通用的语言,但是它并没有实现面向对象的原则。这意味着,要实现代码重用可能更为困难。当然,可以使用一些技巧来使JavaScript看上去更象传统的面向对象语言。不过即使如此,要实现托管语言中的例如事件和代理等特征仍然相当困难。
其它困难还包括:缺乏一个可重用框架来进一步提高JavaScript的开发效率。如果有一种基于JavaScript的能够隐蔽不同执行环境区别的UI框架或许更好些。另外,如果能够创建一组类,它们可以用一种安全的方式(相对于手工编码SOAP包并使用XMLHttp来传递它们)来调用Web服务,也会相当不错。
最近来自微软的Atlas工程许诺要重点解决这类问题。这是一种极大程度地简化AJAX风格开发的伟大尝试。Atlas提供了一种新的JavaScript框架(注意,下面是基于微软的一次初步宣布,以后有可能发生改变)-UI开发工具包。这其中包括:支持诸如拖放和数据绑定等特征的常用控件;调用Web服务的SOAP栈;隐蔽浏览器差别的浏览器兼容层;包括例如本地缓冲等内容的客户端构建模块。另外,ASP.NET团队还计划为ASP.NET开发其它构建模块,例如配置管理,成员管理等,以便把它们用作Web服务端点,从而实现可以直接从JavaScript中对Web服务进行存取-例如可以容易地从客户端存取个人信息。最后,Atlas工程还计划扩展JavaScript语法以便包括接口、生命周期管理和multicast事件。
据说,接下来的几个月将是令AJAX开发者激动的日子。因此,我非常希望本文能够激起您对AJAX的兴趣,并在你以后构建下一代Web应用程序时优先考虑使用这一技术。
0
相关文章