asp net ajax part 2 client side data binding

17
ASP.NET AJAX: Part 2 - Client- Side Data Binding Microsoft ® Virtual Labs

Upload: balaji-uppala

Post on 07-Apr-2015

303 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Microsoft® Virtual Labs

Page 2: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Table of Contents

ASP.NET AJAX: Part 2 - Client-Side Data Binding ................................................................. 1

Exercise 1 Build a Data Service .................................................................................................................................... 2

Exercise 2 Create a ListView Template ........................................................................................................................ 6

Exercise 3 Add DataSource and ListView Controls ...................................................................................................... 9

Summary...................................................................................................................................................................... 15

Page 3: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 1 of 15

ASP.NET AJAX: Part 2 - Client-Side Data

Binding

Objectives After completing this lab, you will be better able to:

� Create a data service for use with client-side data binding

� Use DataSource controls to provide a client-side interface to data services

� Use ListView controls to perform client-side data-binding

� Declare controls, bindings, and other objects using xml-script

Estimated Time to Complete This Lab

90 Minutes

Page 4: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 2 of 15

Exercise 1 Build a Data Service

Scenario In this exercise, you’ll build the server-side infrastructure to support a shopping cart page by building a data service

to serve as the data source for client-side data binding.

Note: If you prefer to Copy & Paste code instead of typing, you can use the version of the lab manual included on

the Desktop of the Virtual Machine.

Tasks Detailed Steps

1. Open the Web site Note: Logon to the server using following credentials:

Username: John

Password: Pass@word1

a. Open Visual Studio 2005. You will see “ASP.NET AJAX Lab 2” in the list of

Recent Projects. Open this Project.

Note: If you are notified that “Administrator permissions are recommended for

running Visual Studio 2005 SP1”, click Continue. This lab does not require

Administrator permissions.

b. You will need to open Site.master and add the following markup just after the

opening <form> tag to declare a ScriptManager control in the site’s master page:

<asp:ScriptManager ID="MasterScriptManager"

runat="server">

</asp:ScriptManager>

c. Then save your changes and close Site.master.

Note: Pages that use ASP.NET AJAX must declare an instance of ScriptManager.

Among other things, the ScriptManager control ensures that the core JavaScript files

comprising the Microsoft AJAX Library get downloaded to the client.

2. Create the shopping

cart Web service

a. Use Visual Studio’s Website->Add New Item command to add a Web service

named ShoppingCart.asmx to the Web site.

Page 5: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 3 of 15

Tasks Detailed Steps

b. Replace the contents of ShoppingCart.cs (found in App_Code) with this:

using System;

using System.Web;

using System.Collections;

using System.Collections.Generic;

using System.ComponentModel;

using System.Web.Services;

using System.Web.Services.Protocols;

using System.IO;

using System.Xml;

using System.Xml.Serialization;

using Microsoft.Web.Preview.Services;

using System.Web.Script.Services;

[ScriptService]

public class ShoppingCart : DataService

{

public ShoppingCart()

{

}

[WebMethod(EnableSession = true)]

[DataObjectMethod(DataObjectMethodType.Select)]

public ShoppingCartItem[] GetCartItems()

{

// Pull shopping cart cookie

HttpCookie cookie =

HttpContext.Current.Request.Cookies["ShopCartID"];

// Call shopping cart data service to retrieve

cart items for this user

ShoppingCartItem[] cartItems = new

ShoppingCartItem[0];

if (cookie != null)

Page 6: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 4 of 15

Tasks Detailed Steps

{

// Pull the user's cart

cartItems =

new

ShoppingCartDataService().GetCartItems(cookie.Value).CartI

tems;

}

return cartItems;

}

[WebMethod(EnableSession = true)]

[DataObjectMethod(DataObjectMethodType.Update)]

public void UpdateCart(ShoppingCartItem cartItem)

{

// Pull shopping cart cookie

HttpCookie cookie =

HttpContext.Current.Request.Cookies["ShopCartID"];

// Call shopping cart data service to save this

cart item

if (cookie != null)

{

new

ShoppingCartDataService().UpdateCart(cookie.Value,

cartItem);

}

}

}

Note: The Web service you just created has two methods: GetCartItems, which returns

shopping cart items to the client, and UpdateCart, which accepts data from the client

and updates the shopping cart data store. Note the [DataObjectMethod] attributes

identifying one method as the “Select” method and the other as the “Update” method.

Also note the [ScriptService] attribute decorating the Web service itself. This attribute

is required if the Web service is to be called by an ASP.NET AJAX client.

Note: Also observe that the Web service derives from DataService rather than

WebService. DataService is defined in the Microsoft.Web.Preview.Services

namespace. It identifies a Web service as a “data service”—that is, one that contains

specially designated methods for performing selects, inserts, updates, and deletes.

Note: The infrastructure that the Web service relies on has already been provided for

you. ShoppingCartDataService, which you’ll find in the App_Code folder, is a data

component used to access shopping cart data. ShoppingCartDataService, in turn, uses

the XmlCartProvider class (found in App_Code/Providers) to access the data store.

The data store is nothing more than an XML file (App_Data/ShoppingCart.xml), but

because of the provider-based architecture used here, you could easily modify the site

to store shopping cart data in a database instead.

Note: The products in ShoppingCart.xml are REAL products from Burton, makers of

fine snowboards and snowboarding accessories and generally wild and crazy people.

Visit their Web site at http://www.burton.com to see the products first-hand. In fact,

the markup we’ll use to display the shopping cart items is patterned after the markup

in the real Burton Web site.

c. Test the Web service by launching ShoppingCart.asmx in your browser. Use the

autogenerated test harness to invoke the service’s GetCartItems method. Verify

that the output resembles that pictured below.

Page 7: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 5 of 15

Tasks Detailed Steps

d. Close your browser and return to Visual Studio.

Page 8: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 6 of 15

Exercise 2 Create a ListView Template

Scenario In this exercise, you’ll create a template that an ASP.NET AJAX ListView control can use to format the markup that

it generates on the client. The template is contained in a hidden DIV to prevent it from being seen. The hidden DIV

is accompanied by an empty DIV that marks the location on the page where the ListView will ultimately position

the markup that it generates.

Tasks Detailed Steps

1. Link to the shopping

cart page from

Site.master

a. Although a partially completed version of ShoppingCart.aspx is already present

in the Burton Starter Kit, the “Shopping Cart” link in the master page points to

the site’s coming-soon page (ComingSoon.aspx). You’ll need to edit that link to

point to ShoppingCart.aspx. Begin by opening Site.master for editing.

b. Find the HyperLink control whose ID is “ShopOnlineHyperLink”.

c. Change the HyperLink’s NavigateUrl property to “~/ShoppingCart.aspx”.

d. Save your changes to Site.master.

2. Import

PreviewScript.js

a. Open ShoppingCart.aspx in Visual Studio.

b. Import PreviewScript.js by adding the following ScriptManagerProxy

declaration inside the <asp:Content> element:

<asp:ScriptManagerProxy

ID="ShoppingCartScriptManagerProxy" runat="server">

<Scripts>

<asp:ScriptReference Name="PreviewScript.js"

Assembly="Microsoft.Web.Preview" />

</Scripts>

</asp:ScriptManagerProxy>

Note: ScriptManagerProxy controls allow you to add script and service references to

ScriptManager controls declared in master pages. The ScriptReference element in this

example downloads the core ASP.NET AJAX CTP file (PreviewScript.js), which

contains the ListView and DataSource control used in this lab.

3. Create a placeholder

for ListView output

c. Near the top of the ShoppingCart.aspx, you’ll find a comment that reads “Add

the cart markup here.” Replace the comment with the following DIV:

<div id="cartResults">

</div>

Note: This DIV, while empty at the moment, will be filled with content when the

ListView renders out its data.

4. Create an item

template and a

separator template

a. Underneath the DIV you just added is a DIV with the ID “cartLayoutTemplate.”

This is the template the ListView control will use to format the markup it

generates. Look through the template and find the comment that reads “Add the

TBODY element here.” Replace the comment with an empty TBODY element:

<tbody id="cartResults_itemTemplateParent">

</tbody>

Page 9: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 7 of 15

Tasks Detailed Steps

b. Now add the following markup to the TBODY element to define an item template:

<tr id="cartResults_itemTemplate">

<td class="col6Shopping">

<span class="blank">&nbsp;</span>

<input type="checkbox" id="ItemRemoved" />

</td>

<td class="col1Shopping">

<a id="ItemLink" href="">

<img style="float: left; padding: 0 10px 10px 0;

border: none"

id="ItemImage" src="" alt="" />

<br />

<span id="ItemName" class="productAttr"></span>

</a>

<br />

<span id="ItemDesc"

class="cartShortDescription"></span>

</td>

<td class="col2Shopping">

<span class="required">*</span>

<input type="text" class="inputShopQty" id="ItemQty"

value="1" size="2" />

</td>

<td class="col3Shopping">

<span id="ItemPrice"></span>

</td>

<td class="col4Shopping">

<span id="QtyTotal"></span>

</td>

</tr>

Note: If you’re familiar with ASP.NET data-binding controls, the item template you

just created is analogous to an <ItemTemplate> in a Repeater control.

c. Like ASP.NET Repeater controls, ASP.NET AJAX ListView controls support

separator templates—templates that define the markup inserted between items the

control renders out. Following the markup you added in the previous step, add this

TR element to define the format of item separators:

<tr id="cartResults_itemSeparator" class="greenDotted560">

<td colspan="5"></td>

</tr>

5. Create an “empty

cart” template

a. You now have a template in place for shopping cart items. But what happens if the

cart is empty and there are no items? ListView controls allow you to define

“empty” templates that are analogous to the ASP.NET GridView control’s

<EmptyDataTemplate>. To add an empty template, locate the closing DIV tag for

the “cartLayoutTemplate” DIV (it’s marked with a comment that reads “Add the

empty cart markup here”). Replace the comment with the following DIV:

<div id="cartResults_emptyTemplate">

<span class="col1Shopping">

There are currently no items in your shopping cart!

</span>

Page 10: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 8 of 15

Tasks Detailed Steps

</div>

Note: That’s it! Your templates are set up and ready to go.

Page 11: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 9 of 15

Exercise 3 Add DataSource and ListView Controls

Scenario You have nearly all the pieces in place to create a stunning client-side data-bound shopping cart page. In the final

exercise, you’ll use xml-script to declare a ListView control and a DataSource control and wire the two together.

You’ll also add some JavaScript to lend a helping hand.

Note: xml-script is a declarative markup language featured in the ASP.NET AJAX January Futures CTP. It allows

you to declare instances of controls using XML elements such as <listView> and <dataSource>. It also lets you

initialize control properties, bind data sources to data consumers, handle control events, and more. xml-script is

often more intuitive than JavaScript for programming templated controls.

Tasks Detailed Steps

1. Add xml-script a. Add the following xml-script block to ShoppingCart.aspx just above the

</asp:Content> tag at the end of the file:

<script type="text/xml-script">

<page xmlns:script="http://schemas.microsoft.com/xml-

script/2005" >

<components>

</components>

</page>

</script>

b. Add the following element to the xml-script block (between the <components> and

</components> tags) to declare a DataSource control that connects to

ShoppingCart.asmx on the server:

<dataSource id="cartDataSource"

serviceURL="ShoppingCart.asmx" autoLoad="true"

dataAvailable="tallyTotal" />

Note: There are three items of note here. First, for security reasons, the serviceURL

attribute must refer to a Web service in the same domain as the application itself.

Second, autoLoad=“true” tells the DataSource control to automatically call the data

service’s select method when the page loads. Without that, you’d have to write code to

make the initial call yourself. Finally, the DataSource control fires a dataAvailable

event after the data is downloaded. The dataAvailable attribute registers a handler

named tallyTotal for that event. tallyTotal, which you haven’t written yet, sums the

prices of the items in the shopping cart.

c. Now declare a ListView control right after the DataSource control:

<listView id="cartResults"

itemTemplateParentElementId="cartResults_itemTemplateParen

t">

</listView>

Note: The id and itemTemplateParentElementId attributes refer to elements in the

markup. The id attribute identifies the DIV that serves as a placeholder for the

ListView control’s output; itemTemplateParentElementId identifies the element that is

Page 12: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 10 of 15

Tasks Detailed Steps

the parent of the item template.

d. Add the following markup to the body of the ListView control—that is, between

the <listView> and </listView> tags:

<bindings>

<binding dataContext="cartDataSource" dataPath="data"

property="data" />

</bindings>

<layoutTemplate>

<template layoutElement="cartLayoutTemplate" />

</layoutTemplate>

<separatorTemplate>

<template layoutElement="cartResults_itemSeparator" />

</separatorTemplate>

<emptyTemplate>

<template layoutElement="cartResults_emptyTemplate" />

</emptyTemplate>

<itemTemplate>

<template layoutElement="cartResults_itemTemplate">

<checkBox id="ItemRemoved">

<bindings>

<binding dataPath="ItemRemoved" property="checked"

direction="InOut" />

</bindings>

</checkBox>

<image id="ItemImage">

<bindings>

<binding dataPath="ItemImage" property="imageURL"

/>

<binding dataPath="ItemDesc"

property="alternateText" />

</bindings>

</image>

<hyperLink id="ItemLink">

<bindings>

<binding dataPath="ItemLink"

property="navigateURL" />

</bindings>

</hyperLink>

<label id="ItemName">

<bindings>

<binding dataPath="ItemName" property="text" />

</bindings>

</label>

<textBox id="ItemQty">

<bindings>

<binding dataPath="ItemQty" property="text"

direction="InOut" />

</bindings>

</textBox>

<label id="ItemPrice">

<bindings>

<binding dataPath="ItemPrice" property="text" />

Page 13: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 11 of 15

Tasks Detailed Steps

</bindings>

</label>

<label id="ItemDesc">

<bindings>

<binding dataPath="ItemDesc" property="text" />

</bindings>

</label>

<label id="QtyTotal">

<bindings>

<binding dataPath="QtyTotal" property="text" />

</bindings>

</label>

</template>

</itemTemplate>

Note: There’s a lot going on here, but it’s not as scary as it might seem. The first

<binding> element binds the ListView to the DataSource. <itemTemplate>,

<separatorTemplate>, and other elements identify the HTML templates that in turn

define how items, separators, and other content is rendered by the ListView. Inside the

<itemTemplate>, elements such as <image>, <checkBox>, and <label> declare

instances of controls featured in the ASP.NET AJAX January Futures CTP. These

controls wrap the DOM elements with the same IDs. Finally, the <binding> elements

bind properties of the controls to properties of the data source. If you look at the

ShoppingCartItem class in App_Code/CartItems.cs, you’ll see that shopping cart items

implement the properties referenced in the bindings: ItemLink, ItemName, and so on.

2. Add JavaScript a. The xml-script you just wrote does the bulk of the work, but it needs a helping

hand from JavaScript to sum up the prices of the items in the shopping cart and

bind them to a SPAN element, to update the shopping cart when the Update button

is clicked, and to reset the cart to its original state when “Reset Cart” is clicked. To

that end, add the following script block to the page before or after the xml-script

block:

<script type="text/javascript">

function tallyTotal(result)

{

var o = result.get_data();

var c = result.get_rowCount();

var i;

var total = 0;

if (c > 0)

{

for (i = 0; i < c; i++)

total = total +

parseFloat(o.getRow(i).get_rowObject().QtyTotal.substring(

1));

$get('CartTotal').innerText =

formatDollars(total);

}

}

function UpdateCart()

{

var cartDataSource =

Page 14: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 12 of 15

Tasks Detailed Steps

Sys.Application.findComponent('cartDataSource');

if (cartDataSource.get_isDirtyAndReady())

cartDataSource.save();

}

function formatDollars(dollars)

{

var strDollar = (dollars + "");

if (strDollar.charAt(0) == "$")

strDollar = strDollar.substring(1);

var amt = parseFloat(strDollar);

if (isNaN(amt))

return strDollar;

amt = Math.round(100 * amt);

var prefix = "$";

if (amt < 0)

{

prefix = "-" + prefix;

amt = -amt;

}

var retAmt;

if (amt < 10)

retAmt = prefix + "00" + amt;

else if (amt < 100)

retAmt = prefix + "0" + amt;

else

retAmt = prefix + amt;

retAmt = retAmt.substring(0, retAmt.length - 2) +

"." +

retAmt.substring(retAmt.length - 2,

retAmt.length);

return retAmt;

}

function OnReset()

{

PageMethods.ResetCart(ResetCartComplete);

}

function ResetCartComplete()

{

var cartDataSource =

Sys.Application.findComponent('cartDataSource');

cartDataSource.load();

}

</script>

b. Take a moment to examine the code you just entered. The UpdateCart function is

called when the user clicks the page’s Update button. It calls a function in the

Microsoft AJAX Library (“findComponent”) to retrieve a reference to the

Page 15: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 13 of 15

Tasks Detailed Steps

DataSource object declared in xml-script. Then it calls the DataSource’s save

function, which in turn calls the update method of the data service.

Note: Also of interest is the OnReset function, which is called when the “Reset Cart”

button is clicked. It fires off a call to a special type of Web method called a page

method. A page method is a static Web method that’s implemented in an ASPX instead

of an ASMX. Page methods are called using the PageMethods.MethodName syntax.

You haven’t written the ResetCart page method yet, but you’ll take care of that in the

next two steps.

c. Open ShoppingCart.aspx.cs and add the following fields to the code-behind

class:

protected const string OriginalDatabaseFilename =

"~/App_Data/ShoppingCart.original.xml";

protected const string DatabaseFilename =

"~/App_Data/ShoppingCart.xml";

d. Now add the ResetCart page method to the code-behind class:

[WebMethod]

public static void ResetCart()

{

// Open our original "database."

System.Xml.XmlDocument cartDB = new

System.Xml.XmlDocument();

cartDB.Load(HttpContext.Current.Server.MapPath(OriginalDat

abaseFilename));

// Save as our new "database."

cartDB.Save(HttpContext.Current.Server.MapPath(DatabaseFil

ename));

}

Note: ResetCart resets the shopping cart by overwriting the contents of

ShoppingCart.xml with the contents of ShoppingCart.original.xml.

Note: Because ResetCart overwrites the contents of ShoppingCart.xml on the server,

the account that the application runs as requires write access to the Web site’s

App_Data folder. If you’re running the site in Visual Studio using the built-in

ASP.NET Development Server, then your account (the person you’re logged in as)

requires that write permission. If you were running the site in IIS instead, you’d need

to grant write access to whatever account the application is configured to run as

(typically, ASPNET, Network Service, or a designated domain account).

e. Open Site.master and add an EnablePageMethods=“true” attribute to the

ScriptManager control:

<asp:ScriptManager ID="MasterScriptManager"

EnablePageMethods="true"

runat="server">

</asp:ScriptManager>

Note: Page methods are disabled by default. You enable them by setting the

ScriptManager control’s EnablePageMethods property to true.

3. Test the results a. Launch ShoppingCart.aspx in your browser. Verify that the resulting page

Page 16: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 14 of 15

Tasks Detailed Steps

resembles the one below (although you may only see one shopping cart item

displayed at a time because the virtual environment is unable to reference the script

schema at http://schemas.microsoft.com/xml-script/2005):

b. Check one of the “Remove” boxes and click the Update button. Verify that the

item disappears from the page and that the subtotal at the bottom of the page is

updated, too.

c. Click the “Reset Cart” button and verify that the item you deleted reappears—that

is, that the shopping cart is restored to its original state.

d. Close your browser and return to Visual Studio.

Page 17: ASP Net Ajax Part 2 Client Side Data Binding

ASP.NET AJAX: Part 2 - Client-Side Data Binding

Page 15 of 15

Summary Here’s a recap of what you learned in this lab:

• How to create a data service for use with client-side data binding

• How to use DataSource controls to provide a client-side interface to data services

• How to use ListView controls to perform client-side data-binding

• How to declare controls, bindings, and other objects using xml-script

ListView controls also support sorting, paging, and other operations. But that’s a topic for another day!