深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之一
2007-09-10 16:31
591 查看
深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之一
一、上篇中的示例回顾在上篇中,为了熟悉MS AJAX在客户端的数据绑定技术,我们给出了一个简单的例子AJAXCTPDev311。其实,这个例子中还有许多重要的特征值得我们作深入分析:
◆提供了一个创建基本的MS AJAX数据绑定应用程序的典型框架;
◆在创建这个例子时,我们选用了“ASP.NET AJAX CTP-Enabled Web Site”模板;其实,你还可以选择普通的“ASP.NET AJAX-Enabled Web Site”模板,但是你必须手工地添加对程序集Microsoft.Web.Preview.dll(这个程序集提供对xml-script声明方式编程和数据绑定技术的支持)的引用;
◆无论创建什么样的MS AJAX应用程序,MS AJAX服务器端控件ScriptManager在整个MS AJAX框架中都起着核心作用。典型情况下,我们都要显式地指定我们要使用的WEB服务相应的*.asmx文件和所使用的程序集。下面我们再次列出这部分的相关代码:
<asp:ScriptManager ID="ScriptManager1" runat="server" > <Services> <asp:ServiceReference Path="BookDataService.asmx" /> </Services> <Scripts> <asp:ScriptReference Assembly="Microsoft.Web.Preview" Name="PreviewScript.js" /> </Scripts> </asp:ScriptManager> |
◆声明性编程是MS AJAX新提供的一种客户端编程技术,我们将在后面的部分对之作更为深入的讨论;
◆下面的框图大致概括了我们所使用的几个关键部件间的关系:
图1:几个关系部件间的关系图 |
◆在本例中,我们使用了一个特别类型的WebService—DataService来实现从服务器端为客户端的ListView控件提供数据;
◆我们在本例中直接从客户端调用了WebService方法—这是MS AJAX带给我们的巨大变化。
在接下来的部分中,我们将详细更为细致地分析MS AJAX框架提供的xml-script编程(也即声明性编程)思路。
二、MS Ajax中的声明性编程
除了使用直接的JavaScript编程方式外,MS AJAX还提供了另一种实例化客户端类型的方式—声明性编程模式(其实在ASP.NET中已经提供了类似的实现方式)。注意,为了使用这种方式进行编程,你必须从微软Ajax站点下载Futures CTP包并且添加一个到脚本文件PreviewScript.js(包含在程序集Microsoft.Web.Preview中)的引用。有关这种ASP.NET AJAX 1.0声明性编程的更为细致的讨论,你可以参考Alessandro Gallo的xml-script声明性编程教程。但是,即使这里的教程也只是提及了有关xml-script编程的基本知识;因此,要想精通这种声明性编程,我的意见是,一方面你应该深入研磨伴随MS AJAX发行的示例程序—TaskList;更深一步的话,应该是深入研究文件PreviewScript.js中的有关xml-script语法的解析器部分(这是xml-script编程的优点吗?)。
在此,我们仅列出使用声明性编程的基本步骤,具体应用请参考后面的有关例子:
◆按通常方式设计你的WEB页面—定义相应的HTML元素;
◆创建MS AJAX客户端控件以关联于这些HTML元素;
◆操纵这些MS AJAX客户端控件,进而间接控制相应的HTML元素。
为了进一步简化声明性编程,MS AJAX不仅引入了大量的客户端控件(例如Label,Button,InputControl,TextBox,Image,HyperLink,CheckBox,Select,ItemView,ListView,等等),而且还新创建了许多高级概念(例如Action,Behavior,数据绑定等)。
根据本人的理解,使用声明性编程至少存在两个理由:通过配置相应的XML元素或标签来简化单纯的JavaScript脚本式编程(毕竟有大量的WEB开发人员对JavaScript并不深入了解);这也是适应未来编程模式的要求—通过把应用程序的设计与实现分离开来从而简化程序的开发,而且简化系统的维护、更新、国际化、第三方开发、重编译,乃至系统的发布。尽管存在种种优点,但由于这种新模式编程刚刚开始(在其它系统下大概也是如此),所以,也存在一些相关的困难,例如调试问题,尚未出现现成的高级IDE工具来简化这种XML声明式编程。
三、例1—把HTML ListView控件绑定到一个Web服务
(一)设计WEB页面
首先,请注意这个例子与第一部分的那个例子存在很大的相似之处。但是,在此我们将详细分析第一个例子中所没有涉及到的许多问题。现在,请启动Visual Studio 2005并选择模板“ASP.NET AJAX CTP-Enabled Web Site”创建一个新的网站并命名为ListEmployees。下图2展示了这个例子的设计时刻界面。
图2:示例程序的设计时刻界面 |
1.设计WEB页面
列表2
//……省略 <link rel="stylesheet" type="text/css" href="site.css" /> //……omitted <span style="font-size: 24pt; color: #6600cc"> <strong>Employee Info Searching Results:</strong> </span> <div id="header"> <span > <strong>EmpID</strong> </span> <span > <strong>Name</strong> </span> <span> <strong>Address</strong> </span> </div> <hr style="width: 457px" align="left" /> <div id="searchResults"> </div> <div style="visibility:hidden;display: none;"> <div id="searchResults_layoutTemplate"> <div id="searchResults_itemTemplate" > <span id="searchResults_ID"></span> <span id="searchResults_Name"></span> <span id="searchResults_Address"></span> </div> <div id="searchResults_separatorTemplate" class="TaskSeparator"> </div> </div> <div id="NoDataTemplate">Waiting...</div> </div> |
2.创建相应的MS AJAX客户端控件
在此,我们只创建了一个MS AJAX客户端控件ListView来匹配HTML元素(一组div元素)并使其每一个模板相应于不同的div元素。此外,我们还定义了三个label元素以匹配上面的三个span元素。
(二)创建Web服务
右击工程并且选择“添加新项”,然后创建一个新的Web服务,并命名为EmployeeDataService.asmx。注意,我们还要使这个Web服务派生自DataService,然后创建四个相应于典型的数据库操作CRUD的WebMethod。下面展示了相应的关键代码:
列表3
//…… using System.ComponentModel; using System.Web.Script.Services; using Microsoft.Web.Preview.Services; //…… [ScriptService] public class EmployeeDataService : DataService { static List _data; static int _nextId; static object _dataLock = new object(); private static List Data { get { if (_data == null) { lock (_dataLock) { if (_data == null) { _data = new List(); _data.Add(new Employees(0, "John Smitch","1970 Napa Ct.")); _data.Add(new Employees(1, "Mary Smitch","9833 Mt. Dias Blv.")); _data.Add(new Employees(2, "Mike Jodan","7484 Roundtree Drive")); _data.Add(new Employees(3, "Ronald Adina","9539 Glenside Dr")); _data.Add(new Employees(4, "Blue Yonder Airlines","1226 Shoe St.")); _data.Add(new Employees(5, "Milton Albury","1399 Firestone Drive")); _data.Add(new Employees(6, "Phyllis Allen","5672 Hale Dr.")); _data.Add(new Employees(7, "Stanley Alan","6387 Scenic Avenue")); _data.Add(new Employees(8, "Alexander Berger", "8713 Yosemite Ct.")); _nextId = 9; } } } return _data; } } [WebMethod] [DataObjectMethod(DataObjectMethodType.Delete)] public void DeleteRecords(int id) { foreach (Employees row in _data) { if (row.Id == id) { lock (_dataLock) { _data.Remove(row); } break; } } } [WebMethod] [DataObjectMethod(DataObjectMethodType.Select)] public Employees[] SelectRecords() { return EmployeeDataService.Data.ToArray(); } [WebMethod] [DataObjectMethod(DataObjectMethodType.Insert)] public Employees InsertRecords(string name, string Address) { Employees newRow; lock (_dataLock) { newRow = new Employees(_nextId++, name, Address); _data.Add(newRow); } return newRow; } [WebMethod] [DataObjectMethod(DataObjectMethodType.Update)] public void UpdateRecords(Employees updateRow) { foreach (Employees row in _data) { if (row.Id == updateRow.Id) { row.Name = updateRow.Name; row.Address = updateRow.Address; break; } } } } public class Employees { private int _id; private string _name; private string _address; [DataObjectField(true, true)] public int Id { get { return _id; } set { _id = value; } } [DataObjectField(false)] [DefaultValue("")] public string Name { get { return _name; } set { _name = value; } } [DataObjectField(false)] [DefaultValue("")] public string Address { get { return _address; } set { _address = value; } } public Employees() { _id = -1; } public Employees(int id, string name, string address) { _id = id; _name = name; _address = address; } } |
接下来,让我们深入探讨那个“神秘”的DataService。
(三)关于DataService的讨论
在写本文时,我细致地使用关键字“DataService”搜索了整个因特网但却得到极少的几篇与这个主题相关的文章(例如这一篇http://forums.asp.net)。所以,我们的主要参考资料就是随同MS AJAX框架发行的几个例子。此外,我还使用VS2005中的对象浏览器和反射工具搜索到了有关的一少部分信息。现在,我把它们粘合在一起,谈谈自己对这个“神秘”的DataService的理解。
首先,尽管最近你可以从WEB或者是MS AJAX所附教程中非常容易地找到大量的从ASP.NET AJAX框架的客户端JavaScript中消费普通WEB服务相关的操作技巧,但是有关于直接从客户端JavaScript消费派生自DataService的WEB服务方面的内容却实在不多。根据本人的粗浅研究,DataService应该主要使用于如下的典型场所下:当我们使用高级客户端控件ItemView,ListView,而且其数据源来自于WEB服务提供的数据库,并且要求进行数据库相关的典型操作时(例如CRUD);而在其它情况下,我们一般选用普通的WebService。微软是否针对ListView/ItemView特别设计了DataService?通过进一步使用.NET对象浏览器和Lutz Roeder的高级.NET Reflector工具(提示:这是一个相当优秀的工具,借助于它你可以获取类DataService的全部源码)剖析程序集—Microsoft.Web.Preview.dll,我们还注意到DataService派生自WebService,而且只对外暴露了两个Web方法:
列表4
public DataTable GetData(object parameters, string loadMethod); public DataTable SaveData(ChangeList changeList, object parameters,string loadMethod); |
1、方法save要求DataSource的serviceType属性必须为类型Sys.Preview.Data.ServiceType.DataService;之后,方法save被转向调用类DataService的方法SaveData;
2、对于方法load则存在两种情况:当DataSource的serviceType属性为类型DataService时,方法load被转向调用类DataService的方法GetData;而当DataSource的属性serviceType不属于类型DataService时(例如为Handler),系统将创建一个普通的代理,然后把方法load转发到Sys.Net.WebRequest()。当我们使用.NET Reflector来进一步研究类DataService的方法SaveData和GetData时,我们发现了更为有趣的事情—了解DataSource的loadMethod属性的意义以及数据库CRUD操作如何响应于你的DataService的Delete(DeleteRecords),Insert(InsertRecords),Select(SelectRecords)和Update(UpdateRecords)方法的,还蕴含了更多的秘密……
【作者注】极力推荐你研究一下类DataService的实现源码,你将会发现许多有用的东西。
借助于新引入的属性—DataObjectMethod和DataObjectField(你可以参考MSDN中两个类DataObjectFieldAttribute和DataObjectMethodAttribute作进一步研究),我们可以很容易地实现我们的目标—提供为控件DataSource所使用的属性和方法(如Fill,Select,Update,Insert和Delete等操作)。所有这些都可以在下一节中通过轻松的xml-script声明式编程来实现。
(四)实现绑定
现在,我们来看一下如何使用xml-script声明性方式来实现对于控件ListView的数据绑定。下面是相应于前面HTML元素定义部分的xml-script代码部分。
列表5
<script type="text/xml-script"> <page xmlns="http://schemas.microsoft.com/xml-script/2005"> <components> <dataSource id="EmployeeDataSource" serviceURL="EmployeeDataService.asmx" > </dataSource> <listView id="searchResults" itemTemplateParentElementId="searchResults_layoutTemplate" > <bindings> <binding dataContext="EmployeeDataSource" dataPath="data" property="data" /> </bindings> <layoutTemplate> <template layoutElement="searchResults_layoutTemplate" /> </layoutTemplate> <itemTemplate> <template layoutElement="searchResults_itemTemplate"> <label id="searchResults_ID"> <bindings> <binding dataPath="Id" transform="Add" property="text" /> </bindings> </label> <label id="searchResults_Name"> <bindings> <binding dataPath="Name" property="text" /> </bindings> </label> <label id="searchResults_Address"> <bindings> <binding dataPath="Address" property="text" /> </bindings> </label> </template> </itemTemplate> <separatorTemplate> <template layoutElement="searchResults_separatorTemplate" /> </separatorTemplate> <emptyTemplate> <template layoutElement="NoDataTemplate" /> </emptyTemplate> </listView> <application> <load> <invokeMethodAction target="EmployeeDataSource" method="load" /> </load> </application> </components> </page> </script> |
观看运行结果
毋庸多言,请观看图3中的运行时刻结果快照吧!
图3:示例1的运行时刻快照 |
相关文章推荐
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定构架下篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之一(
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之二
- 深入剖析微软ASP.NET Ajax中的数据绑定架构上篇之二
- 深入ASP.NET数据绑定(上)