AspAlliance.com LogoASPAlliance: Articles, reviews, and samples for .NET Developers
URL:
http://aspalliance.com/articleViewer.aspx?aId=1301&pId=-1
Unveil the Data Binding Architecture inside Microsoft ASP.NET Ajax 1.0 - Part 1
page
by Xianzhong Zhu
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 40713/ 78

Overview

Recently, Microsoft ASP.NET Ajax 1.0 has attracted more and more developers’ attention. Why? Because it’s an Ajax-based solution from Microsoft for ASP.NET 2.0 web development! It came to the AJAX stage late in the game, but it brought with it an integral package of new Ajax-based web development technologies that integrate an extensive set of client script libraries with the rich, server-based development platform of ASP.NET 2.0! In this series, I will try to dissect the key techniques in the data binding architecture inside Microsoft ASP.NET Ajax 1.0 Framework. In part 1, we will mainly explore the data binding architecture from the point of view of theory, while in part 2, we'll build two distinct samples (the data sources coming from web services and a SQL Server 2005 database, respectively) to study the practical application of the data binding techniques.

About ASP.NET AJAX Futures January CTP

First, let's take a look at the ASP.NET AJAX framework architecture (Figure 1):

Figure 1: The ASP.NET AJAX Framework architecture

Generally, as far as ASP.NET AJAX (called 'MS AJAX' later in this series) framework is concerned, we refer to the three components as follows:

·         ASP.NET AJAX Essential Components, which corresponds to the assemblies System.Web.Extensions.dll and System.Web.Extensions.Design.dll with three files: MicrosoftAjax.js, MicrosoftAjaxTimer.js, and MicrosoftAjaxWebForms.js inside them.

·         ASP.NET AJAX Control Toolkit (with no hint about it in Figure 1), which provides both ready-to-run samples and a powerful SDK to simplify creating custom ASP.NET AJAX controls and extenders.

·         ASP.NET AJAX Futures January CTP (recently replaced by a May release, with the January one still available), which corresponds to the assembly Microsoft.Web.Preview.dll which contains three files: PreviewScript.js, PreviewGlitz.js, and PreviewDragDrop.js.

The ASP.NET 2.0 AJAX Futures January CTP provides additional features and functionality that work alongside the ASP.NET AJAX Extensions. Together, these releases enable development scenarios supported in the earlier ASP.NET AJAX CTP releases in addition to newly added functionality.

To follow along with the samples in this series, you must first have ASP.NET 2.0 AJAX Extensions 1.0 installed on your computer. Next, you can easily install the ASP.NET 2.0 AJAX Futures January CTP by downloading ASPAJAXCTP.msi and running it on your computer. Please carefully read the release notes which are displayed following installation for more information on using the ASP.NET 2.0 AJAX Futures January CTP with your applications.

Author's Note: Recently, Microsoft has just released another newer version named ASP.NET Futures May 2007 ("Futures") which contains an early developer preview of features (especially the previous ASP.NET AJAX Futures January CTPdiscussed here), as well as provides new features including ASP.NET Silverlight server controls, new functionality for ASP.NET AJAX Extensions, dynamic data controls, enhancements to dynamic languages, and more.

Now, since our main interests lie in the ASP.NET AJAX Futures January CTP, let's do further research into it.

Introduction to the client-side controls in namespace Sys.Preview.Data

Undoubtedly, data plays a core role in nearly every application. One of the most noted features of MS AJAX is that applications update the web page asynchronously with the data fetched from the server, such as the client-side JavaScript can connect with web services directly. In early times, in order to obtain data from inside web services to be supplied to applications we have to first create a server-side application, such as a web form, and achieve the communication with the web services letting the system generate the necessary proxies. But now, with the client-side JavaScript libraries of the MS AJAX framework, you can access your required web services directly from the browser side. Further, this process can be surrogated by the client-side data source controls implicit getting the required data and transfer it to visual controls via data binding. This is so important that the client can exchange data with the server without any intermediate ties, which greatly simplifies the development.

From Figure 1 above, careful readers should have noticed a componentBase Class Library (which corresponds to the file PreviewScript.js) which is the core of ASP.NET AJAX Futures January CTP. This library consists of the namespaces and classes shown in Figure 2.

Figure 2: The Base Class Library components

Seen from the above figure, all the client-side controls bond to the database and those responsible for obtaining datasets from web services are all defined inside namespace Sys.Preview.Data. All the stuffs included in namespace Sys.Preview.Data are: IData, DataRowState, SortDirection, ServiceType, DataColumn, DataRow, DataRowView, DataRowCollection, DataTable, DataView, DataFilter, PropertyFilter, DataSource, XMLDataSource. OK let's study the most important ones of them one by one.

DataSource control

You have to manage data in most of your web applicationsI mean retrieving and displaying data to users and saving them back to a database after modification. This is a common task that we have to perform in almost every project, so ASP.NET abstract it as a build-in object, DataSource. MS AJAX client side script library, as well as ASP.NET, has the same concept of DataSource. Figure 3 shows the advanced data binding controls in MS AJAX vs. their possible ADO.NET 2.0 counterparts.

Figure 3: The MS AJAX client-side DataSource-related controls compared with their ADO.NET 2.0 counterparts

Author's Note: In the new AJAX Futures CTP (January 2007), DataSet was deleted inexplicably (I've fine combed all the related *.js files but only found DataSetConverter supported in PreviewScript.js).

There are two kinds of DataSource in the AJAX Futures CTP:

·         Sys.Data.DataSourcerepresents a tabular data structure such as the result of a query to the database, similar to object SQLDataSource in ASP.NET 2.0. This control can be used as the client side data source of ListView and ItemView controls. You can load data from the server and save the changes back to the server after the user modifies them.

·         Sys.Data.XMLDataSourcerepresents a hierarchy data structure such as an XML file, similar to the XMLDataSource object in ASP.NET 2.0. This control can be used as the client side data source of XSLTView control. This is a read only data source that you can only read data and show it to user but not save the modifications back to the server.

Note that in this series, we'll only explorer the former.

Since all the client-side advanced data binding controls are included inside file PreviewScript.js, let me give another figure (Figure 4) to describe the relationships between them although some of them are to be observed later.

Figure 4: The hierarchical relations between the controls we are interested in

The following Listing 1 is the prototypes and descriptors defined inside the DataSource control:

Listing 1: Prototypes and descriptors defined inside control DataSource

Sys.Preview.Data.DataSource.prototype</span> = {
    _data: null,
    _initialData: null,
    _autoLoad: false,
    _serviceURL: "",
    _loadMethod: "",
    _serviceType: Sys.Preview.Data.ServiceType.DataService,
    _isReady: true,
    _dataChangedDelegate: null,
    _request: null,
    _timeout: 0,
    //……omitted
    _onDataAvailable: Sys$Preview$Data$DataSource$_onDataAvailable,
    get_data: Sys$Preview$Data$DataSource$get_data,
    set_data: Sys$Preview$Data$DataSource$set_data,
    get_initialData: Sys$Preview$Data$DataSource$get_initialData,
    set_initialData: Sys$Preview$Data$DataSource$set_initialData,
    get_isDirtyAndReady: Sys$Preview$Data$DataSource$get_isDirtyAndReady,
    get_isReady: Sys$Preview$Data$DataSource$get_isReady,
    _set_isReady: Sys$Preview$Data$DataSource$_set_isReady,
    get_loadMethod: Sys$Preview$Data$DataSource$get_loadMethod,
    set_loadMethod: Sys$Preview$Data$DataSource$set_loadMethod,
    get_parameters: Sys$Preview$Data$DataSource$get_parameters,
    get_serviceURL: Sys$Preview$Data$DataSource$get_serviceURL,
    set_serviceURL: Sys$Preview$Data$DataSource$set_serviceURL,
    get_serviceType: Sys$Preview$Data$DataSource$get_serviceType,
    set_serviceType: Sys$Preview$Data$DataSource$set_serviceType,
    get_rowCount: Sys$Preview$Data$DataSource$get_rowCount,
    initialize: Sys$Preview$Data$DataSource$initialize,
    onDataPropertyChanged: Sys$Preview$Data$DataSource$onDataPropertyChanged,
    onRequestComplete: Sys$Preview$Data$DataSource$onRequestComplete,
    onLoadComplete: Sys$Preview$Data$DataSource$onLoadComplete,
    ready: Sys$Preview$Data$DataSource$ready,
    load: Sys$Preview$Data$DataSource$load,
    save: Sys$Preview$Data$DataSource$save
}
Sys.Preview.Data.DataSource.descriptor</span> = {
    properties: [ { name: 'data', type: Object },
                  { name: 'autoLoad', type: Boolean },
                  { name: 'initialData', type: String },
                  { name: 'isDirtyAndReady', type: Boolean, readOnly: true },
                  { name: 'isReady', type: Boolean, readOnly: true },
                  { name: 'loadMethod', type: String },
                  { name: 'rowCount', type: Number, readOnly: true },
                  { name: 'serviceURL', type: String },
                  { name: 'parameters', type: Object, readOnly: true },
                  { name: 'serviceType', type: Sys.Preview.Data.ServiceType } ],
    methods: [ { name: 'load' },
               { name: 'save' } ],
    events: [ { name: 'dataAvailable', readOnly: true } ]
}
Sys.Preview.Data.DataSource.registerClass('Sys.Preview.Data.DataSource', Sys.Component);

According to my analysis, all stuffs within the prototype block can be used with JavaScript programming, while only those within the descriptor block can be used in xml-script declarative programming (we mainly discuss this approach).

Events defined in DataSourcedataAvailable

The only self-defined and most important event is dataAvailable. This event is triggered when data inside the DataSource control are loaded completely. We can grab a typical case for this event from the example Tasklist shipped with MS AJAX, as follows:

Listing 2: Typical usage for event dataAvailable inside control DataSource

        <components>
            <dataSource id="listsDataSource" serviceURL="TaskListDataService.asmx" />
            <dataSource id="itemsDataSource" serviceURL="TaskItemDataService.asmx">
                <dataAvailable></span>
                    <invokeMethodAction target="listsDataSource" method="load" /></span>
                </dataAvailable></span>
            </dataSource>

Here, two DataSource controls are defined declaratively. When the second DataSource itemsDataSource are loaded completely, the load method of the first DataSource is then invoked.

Methods self-defined (no including those defined in the parent) in DataSource

Method name

Description

load

Retrieves data from serverexplicitly submit queries to the server side according to the profile of current DataSource.

save

Explicitly writes or updates data to the server side according to the profile of current DataSource, i.e. saves client side changes back to server.

 

Here's the definition for method save of control DataSource in file PreviewScript.js:

Listing 3

function Sys $Preview $Data $DataSource $save()
{
  //……omitted
  if (this._serviceType ==  = Sys.Preview.Data.ServiceType.DataService)
  {
    var method = "SaveData";
    var params =
    {
      changeList: changes, parameters: this._parameters, loadMethod:
        this._loadMethod
    };
    var onComplete = Function.createDelegate(this, this.onLoadComplete);
    var onError = Function.createDelegate(this, this.ready);
    this._request = Sys.Net.WebServiceProxy.invoke(this._serviceURL, method,
      false, params, onComplete, onError, this, this._timeout);
  }
  else
  {
    throw Error.createError("Save is not supported in Handler mode.");
  }
}   

Obviously seen from the code above, only when the type of property serviceType is set to type DataService can method save be available. This is of great importance when we define web services to be consumed from the client side later. And as for the mysterious methodSaveData, we'll discuss it in Part 2.

Properties defined in DataSource

Property name

Description

autoLoad

Boolean value indicating whether this data source control will load data automatically from server after initializing. You should use InitialData instead of using this property if you want to load the data with the page loads, for it needs an extra round to serve right after the page loads.

initialData

Initial data that comes with the page. If there should be some initial data on your page when a user hits the page for the first time, for example, the first page of records of your list. Then we can use an Atlas server side control InitialData to send the data with the page source, to avoid querying the server again right after page loads.

isDirtyAndReady

Indicates whether this DataSource finished loading data and the data is not empty and the data is not changed.

loadMethod

Another mysterious method to be discussed in relation to DataService in Part 2 of this series.

rowCount

Row count of the data.

serviceURL

URL of the Web Service where the DataSource can retrieve data from. You should always set this property.

parameters

Parameters append to the service URL. Only used when serviceType is set to Handler.

serviceType

Type of web service. Can be set to DataService or Handler. Default and recommended value is DataService, which means your service is derived from Microsoft.Web.Services.DataService and has the build-in supports for typical database CRUD operations.

Id (defined in parent)

Identifying the control.

data

The data retrieves from database and stores in the client side.

Important note: this property can only be of type of Array or Sys.Preview.Data.DataTable.

isReady

Indicates whether this DataSource finished loading data from server. You may bind this property to a data bind control’s enabled property to disable the binding control when the data is in loading.

Next comes another DataSource related controlDataView.

DataView control

Generally, we can get data from server side and store them in client side by using DataSource and then modify the data we get on client side using DataTable (discussed later on) object. However, sometimes we need to do some decorations before showing, for example, we may need to page our data if it contains thousands of rows, or our user may be only interested in some of the data. That’s the reason why the framework has to introduce the DataView and DataFilter objects.

Properties defined in DataView

Property name

Description

data

The actual data for decorating. You should always set a DataTable get from DataSource control to this property to let the DataView know the source data.

filteredData

The filtered data. Such as the paged data or the sorted data.

filters

A collection of DataFilter objects to filter the data. You can specify the DataView a collection of filters and they will be applied to your data one by one. For more information about DataFilter object, please see below.

hasNextPage

Whether there is a next page.

hasPreviousPage

Whether there is a previous page.

length

The number of rows in current page.

pageCount

The number of pages in current DataView.

pageIndex

Current page index.

pageSize

How many rows per page. You should set this property if you need to page your data.

sortColumn

The column you want to sort the rows by. You should set this property if you need the sort feature.

sortDirection

The directions you want to sort. Either Ascending (default value) or Descending.

Notice that DataView object has only one self-defined methodsort. This method will apply the sort operation according to sortColumn property and sortDirection property. Also, you should remember that you may need two additional controls in namespace Sys.Preview.UI.DataDataNavigator and SortBehavior to help you with the paging and sorting issues. Here for integrality, we also give a short introduction to the DataFilter object.

Class Sys.Preview.Data.DataFilter is designed as the abstract base class of all the filters. It provides an abstract method filter for the derived class to implement its specified filter rules.

The Futures January CTP also provides one built-in filterPropertyFilter, which is used for filtering the items by one specified property and its value.

Author's Note: First, this DataView control is quite different from that of ADO.NET 2.0. Second, since our samples in this series are mainly using ListView and ItemView, you can get an example related to DataView from here. And although this one is the former Atlas related, don't worryyou only need a slight modification with it according to the new samples provided in this series.

DataTable control

Now comes another important controlDataTable, which implements the Sys.Data.IData interface. By examining the source code of the samples shipped with MS Ajax, we can easily find that many important controls, such as DataSource, DataView, ItemView, and ListView all use the DataTable control to hold their data. So, when you work with data binding in MS AJAX, you will regularly deal with this control. And still for brevity, we just enumerate its events, properties and methods.

Events defined in DataTable

Event name

Description

collectionChanged

Invoked when the row collection changes (such as adding, deleting, and modifying).

propertyChanged

Invoked whenever one or more properties change. Also can be used to trigger custom actions.

Properties defined in DataTable

Property name

Description

Notes

columns

Return an array of Sys.Preview.Data.DataColumn, similar to the structure of a database table.

type: Array, readOnly: true

keyNames

Return an array of string(s) which describe(s) the key column(s) in the DataTable

type: Array, readOnly: true

length

Return the total record numbers in the DataTable

type: Number, readOnly: true

isDirty

If the data in the DataTable has changed and not written back to the database yet, then this property is set to true; or else false.

type: Boolean, readOnly: true

Methods defined in DataTable

Method name

Description

remove(rowObject)

Delete the row associated with the passed row from current DataTable.

get_length()

Return the total number of row data.

add(rowObject)

Append a new row at the end of current DataTable.

clear()

Delete all the row data in current DataTable.

createRow(initialData)

Create a new Sys.Preview.Data.DataRow according to the current column structure.

getChanges()

Return the modifying operation with the DataTable, with the returned value being one of the following kind of sets:

·         updatedthe newly-updated Sys.Preview.Data.DataRow;

·         insertedthe newly-inserted Sys.Preview.Data.DataRow;

·         deletedthe newly-deleted Sys.Preview.Data.DataRow.

getColumn(name)

Return an object DataColumn from the DataTable according to the passed column name.

getRow(index)

Return an object DataRow according to the passed parameter index.

getItem(index)

Same as the method getRow(index)

Here, we still choose to cut a long story short, leaving the examples telling you everything.

DataColumn control

The DataTable class contains a collection of DataColumn objects and a collection of DataRow objects. Since the client-side DataColumn and DataRow controls are designed to simulate their ADO.NET 2.0 counterpartsDataColumn and DataRow, we can easily figure out their relations from the foregoing Figure 3. Yes, quite similar to the database counterpart, the DataColumn here also possesses the properties listed below.

Properties defined in DataColumn

Property name

Description

Notes

columnName

Returns a string containing the column name.

type: String

dataType

Returns a Sys.Type object describing the data type in this column.

type: Sys.Type

defaultValue

Returns a default value in this column.

 

isKey

Is this column is the key field?returns true if yes, or else false.

type: Boolean

readOnly

To decide whether the data in this column is read onlyreturns true if yes, or else false.

type: Boolean

Note that the DataColumn control does not supply any events methods and only provides a few property related get-and-set methods, such as get_columnName(), get_dataType(), get_defaultValue() etc. General speaking, only these properties are enough for use in practical development.

DataRow control

As with the DataColumn control above, the DataRow control only exposes three properties in its descriptor block of its definitiononly the three ones can be used in xml-script declarative mode.

Properties exposed in the descriptor block of DataColumn

Property name

Description

Notes

$isDirty

If the row data has changed and not written back to the server side yet, then this property is set to true; or else false.

type: Boolean

$index

Returns the corresponding index value of this row in current DataTable.

type: Number

$selected

Check whether this row in the current DataTable is in the selected mode.

type: Boolean

Also, the DataRow control provides a few property related get-and-set methods and support only one eventpropertyChanged which will get fired when one of the above properties is changed.

So much is for the discussion with controls in namespace Sys.Preview.Data. Now, let's continue to examine those inside another namespaceSys.Preview.UI.Data.

Introduction to the client-side controls in namespace Sys.Preview.UI.Data

ItemView control

We need to display user a detailed view about our items in a collection, such as the details about your product in a shopping application. The MS AJAX client-side control ItemView provides this feature for you, just like the ASP.NET server control DetailsView behaviors, but it runs totally on the client side. The ItemView class and ListView class both inherit from base classSys.UI.Data.DataControl, which provides the basic functionalities of a DataControl, including many additional properties.

There are several client-side controls in namespace Sys.Preview.UI.Data, such as DataControl (the parent control of ItemView and ListView), DataNavigator, ItemView, ListView, XSLTView, etc.

Here, we merely concentrate on two controlsItemView and ListView. In practice, as the ASP.NET server control GridView is to ObjectDataSource, so is the MS AJAX client-side control ItemView (or ListView) to DataSource. And also, there exist similar data bindings between the two couples. The following table lists the commonly used and self-defined properties with their short explanations in column two.

Property name

Description

id

Identifying the ItemView control.

canMoveNext

There’s a next record you can move to if true; or else false.

canMovePrevious

There’s a previous record you can move to if true; or else false.

data

It holds all the Sys.Preview.Data.DataTable objects loaded into current ItemView controlthese DataTable objects are obtained from the background by the DataSource control.

dataIndex

Identifies the current record index.

dataItem

Returns the current record based on dataIndex.

Length

Returns the count of all records.

itemTemplate

This template is used for rendering a single item in the list (e.g., use a <tr> tag). It must be contained in the layoutTemplate.

EmptyTemplate

This template is used for rendering an empty message if there’s no item in the data source, or the ItemView is still waiting for the data from server.

Commonly used methods in ItemView

Method name

Description

addItem

adds a new item to the data collection on the client side, and this operation will make the dataset dirty

deleteCurrentItem

deletes current item from the data collection on the client side, and this operation will also make the dataset dirty

moveNext

moves to the next record, and this operation will again t rigger the data binding for the controls defined inside ItemTemplate

movePrevious

moves to the previous record, and this operation will again trigger the data binding for the controls defined inside ItemTemplate

Please note all the operations above are at client side, which just modify the client side data. So if you want to commit the changes to server, you have to call the methods in DataSource.

Obviously, the ItemView is always used to display one record on the client side, while the ListView control discussed next is for listing records within a range satisfying some condition.

ListView control

In most of the current web applications you often have to find a way to show user a table of data. Just as the ASP.NET GridView server control does, MS AJAX ListView control provides the same behavior on client side in the AJAX way. Although you can use traditional ASP.NET 2.0 GridView server control and then simply add an MS AJAX UpdatePanel to let your GridView work in the AJAX way, but this is with low efficiency and not the ‘pure’ MS AJAX way. You may need to use the full client-side MS AJAX control ListView to make things better. Do not be afraid, this is just as simple as the GridView with similar concepts such as ItemTemplate, but keep in mind there’s no IntelliSense provided by the IDE, and so you must pay more attention on typing the code.

Author's Note: In the new Visual Studio "Orcas" JavaScript Intellisense is supported for MS AJAX.

Commonly used properties in ListView

Property name

Description

Id

Identifes the ListView control.

canMoveNext

There’s a next record you can move to if true; or else false.

canMovePrevious

There’s a previous record you can move to if true; or else false.

Data

Same as that of ItemView

dataIndex

Identifying the current record index.

dataItem

Returning the current record based on dataIndex.

Length

Returning record count.

alternatingItemCssClass

Specify the CSS class for alternating items.

layoutTemplate

This template is used for rendering the list container (e.g., use a <table> tag), header (e.g., use a <thead> tag) and footer. You must specify a layoutTemplate for a ListView. This template must contain an itemTemplate, and may contain a separatorTemplate.

itemCssClass

Specify the CSS class for items.

itemTemplate

This template is used for rendering a single item in the list (e.g., use a <tr> tag). It must be contained in the layoutTemplate.

EmptyTemplate

This template is used for rendering an empty message if there’s no item in the data source, or the ListView is still waiting for the data from server.

selectedItemCssClass

Specify the CSS class for selected items.

seperatorCssClass

Specify the CSS class for separators.

seperatorTemplate

This template is used for rendering a separator between items in the list (e.g., use a <hr> tag). It must be contained in the layoutTemplate.

itemTemplateParentElementID

This property defines the parent element of itemTemplate and separatorTemplate. So the items and separators can be repeated in this element (e.g., use a <tbody> tag).

As with ItemView, to use a ListView, you have to provide MS AJAX some templates above to let it know how to render your content. In practice, these templates are generally corresponding to some special HTML elements, such as "<div>", so be careful.

Indeed, enough of theory debate now. So, let's roll up our sleeves and write a simple example!

Start to use data bindinga simple sample

1. Create an ASP.NET AJAX CTP-Enabled Web Site

Launch Visual Studio 2005 and then select menu item "File | New Website…" to create a new website using the template named "ASP.NET AJAX CTP-Enabled Web Site", and name the project AJAXCTPDev311 (select Visual C# as the built-in language). After that, the system should automatically added references to the necessary assembliesMicrosoft.Web.Preview.dll and System.Web.Extensions.dll. And also, you can see a ScriptManager server control automatically added to the page. Simply put, this server control acts as the headquarters of whole ASP.NET AJAX framework.

Next, with a little modification, page Default.aspx finally looks like Figure 5:

Figure 5: The design-time sample web page

With nothing explained, let's first look at the source code behind this aspx page:

Listing 4

<head runat="server">
    <title>Client-Side Data Binding Test</title>
</head>
<body style="font-size: 12pt">
    <form id="form1" runat="server">
        <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>
        <div style="text-align: left">
            <span style="color: #0000cc"><span style="font-size: 24pt">
                <span>
                    Client-Side Data Binding Test</span>
                    <br />
            </span></span>
                
        </div>
        <br />
          
          <div id="header">
          <input type="button"
 id="Button5" value="Get Book by Title" />
          <br />
      </div>
          
        <div id="Book titles to be listed here">
        </div>
        <div id="Books"></div>
        <div style="display:none;">
          <div id="LayoutTemplate">
            <div id="ItemTemplateParent">
              <div id="ItemTemplate">
                  <span id="BookTitle"></span>
              </div>
            </div>
          </div>
          <div id="emptyTemplate">
                        empty...
          </div>
        </div>    
 
        <script type="text/xml-script">
          <span lang=PT><page
 xmlns="http://schemas.microsoft.com/xml-script/2005">
<span lang=PT>            <components>
            <dataSource id="BooksDataSource" serviceURL="BookDataService.asmx"
 />
            
              <button id="Button5" >
                <click>
                    <invokeMethodAction target="BooksDataSource"
 method="load" />
                </click>
              </button>
              
              <listView id="Books" itemTemplateParentElementId="ItemTemplateParent">
              <bindings>
                  <binding dataContext="BooksDataSource" dataPath="data"
 property="data" />
                </bindings>
                <layoutTemplate>
                  <template layoutElement="LayoutTemplate" />
                </layoutTemplate>
                <itemTemplate>
                  <template layoutElement="ItemTemplate">
                    <label id="BookTitle">
                      <bindings>
                        <binding dataPath="Title" property="text" />
                      </bindings>
                    </label>
                  </template>
                </itemTemplate>
                <emptyTemplate>
                  <template layoutElement="emptyTemplate" />
                </emptyTemplate>
              </listView>
              
            </components>
          </page>
        </script>
    </form>
</body>

Here, several points should be noticed:

1.    The necessary .asmx and .js files references should be added as the sub sections under ScriptManager;

2.    We've defined several span and div HTML elements (in bold) which serve as the placeholder of the MS AJAX client-side controlListView. As stated before, ListView has provided serveral useful templateslayoutTemplate, itemTemplate, separatorTemplate, emptyTemplate, and a necessary propertyitemTemplateParentElementId (specifying the parent element of temTemplate and separatorTemplate; this way, the itemTemplate and separatorTemplate related elements can be rendered repeatedly inside it);

3.    Next comes the declarative programming (we'll discuss it more thoroughly in Part 2). To return data to be shown in the ListView control from web services we must use the DataSource control to specify the service URL;

4.    We've defined the ListView architecture, with the necessary templates in response to their former HTML counterparts;

5.    In step 4, we've also set up the bindings to the properties inside the web service;

6.    Last but not least, careful readers should also notice that here we've use declarative mode to invoke the button click event handler, which in turn invokes the load method of DataSource control BooksDataSource.

2. Create a Web Service

Next, we'll write a web service to be consumed from the browser side through declarative mode (and of course OK by manual JavaScript programming). Here, we let the service returns an array of object Book.

Right click the project and choose "Add new item" and create a new Web Service named BookDataService.asmx. Next, in file BookDataService.cs, we are to create our WebMethodGetTitles. Listing 5 shows the crucial code snippet:

Listing 5

using System.Collections.Generic;
using System.ComponentModel;
…………
using System.Data;
using System.Web.Script.Services;
using Microsoft.Web.Preview.Services;
 
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]</span>
public class BookDataService : <span class=Bold>DataService</span>
{
 
    public BookDataService()
    {
        //InitializeComponent(); 
    }
    [DataObjectMethod(DataObjectMethodType.Select)]</span>
    public Book[] GetTitles()</span>
    {
        List<Book _data = new> List<Book>();
        _data.Add(new Book("Hello,this is Title 1"));
        _data.Add(new Book("Hello,this is Title 2"));
        _data.Add(new Book("Hello,this is Title 3"));
        _data.Add(new Book("Hello,this is Title 4"));
 
        return _data.ToArray();
    }
    public class Book
    {
        private string _title;
        public Book(){}
        
        [DataObjectField(true)]</span>
        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }
        public Book(string title)
        {
            _title = title;
        }
    }
}

Here, there are also some points to be emphasized:

1.    According to the official info, we must put the attribute ScriptService before the Web Service so as for the client side to call it;

2.    We have our web service derived from a special WebServiceDataService, which holds some mystery to be discussed in Part 2;

3.    Next, please note that method GetTitles is decorated with a peculiar attribute DataObjectMethod (defined in namespace 'System.ComponentModel'), which with its two argumentsthe first being a DataObjectMethodType that allows you to indicate whether the method is used to Delete, Insert, Select, Fill or Update an item; The second attribute (a Boolean value) is used to indicate whether a certain method is the default for its type of operation. For more details on this attribute, you can refer to this article.

4.    We have seen that attribute is a good way of decorating business objects for data binding in point 3. Here appears another attributeDataObjectField. This attribute has three arguments to allow you to specify whether the property is a primary key and an identity, its length in bytes, and whether or not it's nullable respectively (please look up DataObjectFieldAttribute in MSDN for more details).

OK, we just know that WebMethod GetTitles will return an array of object Book.

3. Consume the Web Service

In fact, this task has already been accomplished. Really it is. According to the explanation of method load of control DataSource, when you click the button Button5, the method load of data source BooksDataSource is invoked, and then WebMethod GetTitles is called with the help of modifier '[DataObjectMethod(DataObjectMethodType.Select)]'. It seems everything becomes so coincidental, and in the end the ListView Books is filled with the data returned by WebMethod GetTitles, with the only property Title bond properly.

4. Running the sample

Without any trouble, press F5 and you will launch the sample. Click the button and you will see the runtime screenshot like Figure 6. Although the outcome is rather simple, we have indeed gone a long way!

Figure 6: The runtime screenshot

5. The last sentence to mention

To properly run this sample, you also have to add the following necessary converters within web.config, or else you'll get nothing.

Listing 6

<system.web.extensions>
  <scripting>
   <webServices>
     <jsonSerialization>
       <converters>
          <add name="DataSetConverter"
 type="Microsoft.Web.Preview.Script.Serialization.Converters.DataSetConverter,
 Microsoft.Web.Preview"/>
           <add name="DataRowConverter"
 type="Microsoft.Web.Preview.Script.Serialization.Converters.DataRowConverter,
 Microsoft.Web.Preview"/>
           <add name="DataTableConverter"
 type="Microsoft.Web.Preview.Script.Serialization.Converters.DataTableConverter,
 Microsoft.Web.Preview"/>
      </converters>
     </jsonSerialization>
   </webServices>
   </scripting>
</system.web.extensions>

For now, we've finished a simple sample in a hurry!

Downloads
Summary

In the first article of this series, we've given an outline for the data binding architecture in MS AJAX Framework. Then we have looked through the main client-side controls used to achieve data binding and their relations. Finally, a simple sample is provided to put in practice the most components discussed in this article. In the second article of this series, we will examine two more complex samples to further grasp the idea with MS AJAX client-side data binding.



©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-04-26 4:20:39 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search