英语阅读推荐:使用AJAX+WF+LINQ制作Google IG式首页

发布时间: 2007-01-28 07:37    作者: 未知    来源: 未知    浏览:    评论

如果你既想学习ASP.NET AJAX,又想学习Windows Workflow Foundation,还想学习LINQ(包括DLinq和XLinq),能够一次过满足你三个愿望的除了Kinder出奇蛋就是本期Random Clipping重点推荐的这篇文章了。

Build Google IG like Ajax Start Page in 7 days using ASP.NET Ajax and .NET 3.0

点击链接打开文章后,相信大部分读者的第一反应都是“哇!那么长,怎么可能看得完啊!”既然文章标题说是用7天时间来制作一个这样的首页,那么你也可以先用del.icio.us把文章收藏下来然后分开几天看。想学新东西当然就要花点时间的啦,当你耐心把Omar Al Zabir这7天的开发记录读完,再结合源代码深入理解一下它的设计,相信你就能对它所用的几种新技术都会有所了解,至少知道在什么开发场景下使用什么能够为你节省时间提高效率。如果你觉得本文也太长了,那么也可以考虑先收藏下来,等到有时间了再看。

简介

首先,我们来看看工作记录之前的介绍部分。第一节的Introduction说明了这个项目的实现结果是比较贴近真正的Google IG的,它允许拖放小部件(widget)、完全个性化的页面、支持多页面等。并且说明它不是一个原型项目或样例项目,而是一个真正在运作的开源的首页:http://www.dropthings.com/。你可以在日常生活中使用它,也可以使用ASP.NET为它开发更多的小部件。

如果你看到这里,还是不是很明白所谓的“首页”是什么,第二节的What is an Web 2.0 Ajax Start page给出了详细的解释。接着第三节的Features简单说明了其功能,其实这些功能就和Google IG几乎完全一样,没有添加任何新的东西。我觉得这个项目对比Google IG,真正应该强调的功能是你可以好像开发普通UserControl那样为它设计小部件(widget),而不需要懂XML和JavaScript,而这正是第四节Widgets所讲的。第五节Technologies说了此项目所用到的技术,看不到ASP.NET AJAX Future CTP字眼吧?那意味着你无需伸手去碰JavaScript了,AJAX实现所需要的最多就是编写服务器端代码调用一下UpdatePanel和Extender。

分层

接下来从分层的角度来了解一下此项目的特色层,包括Web Layer和Data Access using DLinq。在Web Layer小节,作者强调的是“整个应用也就是一个页面”,并且例如加载当前用户设置这样的常见任务是通过调用Workflow来完成的,还通过实测数据说明了Workflow自身的运行时间是很短的。

在Data Access using DLinq小节,作者强调的是使用DLing所附带的SqlMetal.exe来直接生成数据访问类,这些类包含了所有的数据访问代码以及实体(entity)类。然后作者拿DLing根第三方ORM工具比较,说明DLing特有的Projection技术能够根据你所需要的字段生成对应的属性,这个依赖于定制编译器的功能所以是第三方ORM工具暂时无法实现的,它给你带来的好处就是效率的提升,因为你实际上并没有SELECT那些你不会用到的字段。作者还说,如果你不相信DLinq的表现,或者对DLinq抱有一种不怎么好的感觉的话,可以直接用SQL Profiler看看DLinq让数据库实际执行的SQL语句到底是怎么样的。

第一天:使用UpdatePanel制作Widget容器

正所谓万事开头难,第一天要设计的Widget容器也是不容易的,别看最终生成的就是简单的几层嵌套div,要让它能展开/折叠和能被拖放,并且执行起来符合效率要求,就不那么容易。

在这一节里面,你需要重点注意到的就是Extender放置问题,这让设计如何嵌套成为了一个难题。假如Extender放置在UpdatePanel内,每次UpdatePanel更新都会导致整个Extender的客户端代码被销毁然后重新生成,也就要重新初始化一次,最终导致效率低下。因此,要尽量确保Extender都在UpdatePanel的外面,而最终的嵌套设计方案可以看作者的图示。

至于WidgetContainer,它继承自IWidgetHost,这种设计为将来的扩展预留了足够的空间。当前设计的Widget,可以依赖于WidgetContainer的一些特有的功能,也可以仅仅依赖于IWidgetHost从而将来适应其他IWidgetHost容器。

第二天:制作定制的拖放Extender和多栏放置区域

在这一节里面,作者解释了为什么原有的拖放Extender都不适用于此项目的情景,从而需要自己设计一个新的Extender。其实我也认为ASP.NET AJAX和Control Toolkit自带的各种拖放功能确实限制多多,并不能根据你的开发场景所需要灵活定制,所以使用ASP.NET AjAX时几乎可以肯定如果你需要使用拖放就要自己写。当然,这不一定需要从头写起,Future CTP内置了客户端的拖放管理器,你只需要实现两个接口就可以实现拖放。

另外大多数的Extender都是通过异步Postback时在服务器端保存状态,而这对于的首页来说是不可能的,因为用户一次拖放后很可能马上就要进行下一次的拖放,所以这个定制的拖放Extender通过调用Web Service来保存状态。

第三天:制作数据访问层和站点加载

作者在这一节里展示了此项目的数据库设计,并且说明了如何跨层地通过DLinq访问数据。跨层使用DLinq的问题就在于,如果你的实体用于各个不同的层,那么它就从加载它的DataContext分离(detach)出来了,通常业务逻辑层是没有DataContext的,所以你要将它发回到数据访问层然后利用DataContext更新,通常我们的做法是业务逻辑层修改实体然后再发回给数据访问层,而DLinq则要求先把实体附加(attach)到DataContext再作出修改然后提交更新。

作者使用了delegate来解决这个问题,调用数据访问层的更新函数时传入一个delegate,然后数据访问层把实体附加到DataContext,接着调用该delegate,最后提交更新。而该delegate指向的函数则放在业务逻辑层,这样就保持了原来的分层,并且按照DLinq所需的方式来完成更新,虽然这导致调用在两个层之间往返多了一次。另外,同样的设计方式可用于插入与删除。

第四天:使用XLinq制作Flickr照片与RSS小部件

作者想做的第一个小部件用于显示Flickr照片。首先通过XElement把RSS加载上,然后使用XLinq将XML影射为对象集合,接着还是通过XLinq迭代集合中特定范围的对象并且构建对应的控件树,就那么简单,通用的RSS小部件也用类似的方式制作。想象一下如果没有XLinq你会如何去完成这部分功能,再看看作者给出的代码,你就知道XLinq为你节省多少时间了。

值得注意的是,作者使用了HtmlGenericControl来生成链接,而不是用HtmlLink,因为HtmlLink不允许有子控件,这是它特有的一个局限,而HtmlGenericControl就能很好的解决此问题。

第五天:制作业务逻辑层中的工作流

这是问题多多的一天,把DLinq和WinFX混合在一起不是一件容易的事情,作者就需要解决以下问题:

  • 在ASP.NET中同步调用Workflow
  • Workflow运行完后将对象取出来
  • 在一个Workflow同步调用另一个Workflow

第一个问题通过对WorkflowRuntime添加两个Service解决了。第二个问题,通过创建一个叫做CallWorkflowActivity的新Activity来解决,这个Activity的实现非常复杂,有兴趣了解其细节的朋友可以看这篇文章:A workflow sample。由于Workflow本身是设计为异步执行的,然而ASP.NET的服务器端处理却要求是同步的,所以才会遇到这两个问题。第三个问题源自Workflow是设计为可休眠的,这时候就要对它的数据进行序列化然后持久,然而DLinq的实体却不是可序列化的。解决这个问题的方式是把DLinq实体放到Dictionary<string, object>里面,从而通过要求对象可序列化的检查。

另外要在同一个项目里同时加载WinFX和DLinq的编译器是需要通过修改项目文件的,作者给出了修改方法。不过修改后Workflow的声明性Rules无法正常编译,因为.rules文件无法被正常识别为嵌入资源,这看起来是一条死路。直到第二天清晨,周围一片寂静,太阳准备升起,作者听到了来自天堂的神圣启示,然后明白到如何把这个问题解决掉,想了解详情的就仔细读读原文吧。

第六天:页面切换问题

页面切换时,新页面的小部件被第一次加载,而如果它们通过IsPostBack属性判断自己是否第一次加载的话,就会得到错误的信息,然后尝试根据ViewState恢复上一次的状态也就会失败,从而无法正常初始化。解决方法自然是通过WidgetContainer主动通知Widget这是不是你的第一次加载。

在这里我要加插一些题外话,我觉得这不是一个有效解决问题的办法。如果你设计一个Widget,在上面扔一个DataSourceControl和一个DataBoundControl,就可能导致加载失败,因为这些控件本身就设计为依赖于IsPostBack属性,它们自动根据IsPostBack属性来决定是否需要数据绑定。希望ASP.NET 3.0将这个问题解决了,因为我们确实会有需要动态加载DataBoundControl的时候,它们第一次加载时需要进行数据绑定,而此时IsPostBack属性却为true。

第七天:注册

是时候准备迎来第一个注册用户了,这时候需要将他在匿名访问时使用的设置复制到注册用户中去。因为匿名用户的信息不保存在aspnet_membership,而仅保存在aspnet_user和aspnet_profile,所以不能使用Membership.GetUser获取到匿名用户的实体然后获取其设置,这时候就需要手动访问数据库完成上述复制操作了。

在使用DLinq查询ASPNETDB之前,首先你要看Omar Al Zabir的另一篇文章:Careful when querying on aspnet_users, aspnet_membership and aspnet_profile tables used by ASP.NET 2.0 Membership and Profile provider。ASPNETDB里面的索引都是使用ApplicationId和LowerUserName或LowerEmail组合的,为了确保查询时通过索引以确保效率,你也必须使用上述组合作为查询条件。

收尾

因为这个项目混合了ASP.NET AJAX、WinFX和LINQ,所以必须有一个混合型的web.config以令它们和谐共处,这正是Web.config walkthrough小节要说的事情。接着Deployment Problem和How to run the code两个小节说明了你应该如何部署这个项目,并且让它运行起来。之后Next Steps小节说明了你可以使用ASP.NET为此项目开发更多的小部件,而Conclusion小节则说明了混合这3种技术到一个项目里是多么有挑战性的事情,不过它们也大大降低了你的开发难度。

总结

中间我跳过了How slow is ASP.NET Ajax这一小节没说,在这里作者说明了当一个页面的UpdatePanel和Extender的数量增加到一定程度时,客户端的执行速度将变得非常低。后来作者根据Scott Guthrie的提醒,在web.config中设置debug="false",这将关闭客户端脚本运行时的验证功能,执行速度已经比较好,在IE7、FF和Opera9中速度有明显的提升,然而在IE6中还是比较慢。

这说明了对于只有一个页面的AJAX应用来说,使用UpdatePanel和Extender并非是一个很好的解决方案,除非你有足够的能力通过各式hacking来提升执行效率。然而我觉得,如果你有那样的能力,干脆就用Future CTP开发以客户端为中心的AJAX应用好了,可以尽量减少对服务器端控件与Extender的依赖。

最后,感谢你阅读本期Cat in dotNET(http://purl.oclc.org/NET/CatChen/dotNET)的Random Clipping。你可以通过订阅Cat in dotNET以获取更多此类文章,Feed订阅地址为:http://feeds.feedburner.com/CatChen/dotNET,Email订阅地址为:http://www.feedburner.com/fb/a/emailverifySubmit?feedId=573799



TAG

Smile Big Smile Surprise Stick out tongue Wink Sad Tongue Tied Indifferent Crying Embarrassed Cool Angry Angel Devil [8-|] [:#] [:-*] [:^)] [<:o)] [|-)] Yes Beer Left Hug Music Star Time Snail Pizza Automobile Umbrella Computer Storm [mo] [8o|] [^o)] [+o(] [*-)] [8-)] Coffee No Drinks [Z] Right Hug Cake Broken Heart Gift Wilted Flower Movie Dog Idea Sleep Email Travel Paradise
呢称:

加粗 斜体 下划线 链接 图片 代码 邮件地址 引用 列表

最多只能输入100个字符

Tags

SQL 数据库 asp.net C# XML 控件 .NET教程 程序 事件 数据 安全 代码 Server 客户端 验证 数据库专栏 接口 文件 Oracle DataSet 函数 DataGrid 问题 .net return C#语言 JavaScript 服务 IIS 对象 语句 windows 继承 时间 web.config 设计 开发 参数 变量 解决 字符 ADO.net 环境 VB.Net语言 web 异常 工具 服务器 计算 实例 OLEDB Application VB Word WebService insert asp net 安装 记录

精华推荐

更多

精品下载

更多