Home / AJAX

HOW TO Call ADO NET Web Services

RSS
Modified on 2009/12/04 17:57 by Stephen Walther Categorized as Uncategorized
ADO.NET Data Services provides a powerful REST-based API that can be used to interact with backend data. By making simple URL-based requests, data can be queried, inserted, updated and deleted from the client-side. The ASP.NET Ajax Library provides built-in support for working with ADO.NET Data Services through the MicrosoftAjaxAdoNet.js file and provides an AdoNetDataContext component. This tutorial will demonstrate how to interact with ADO.NET Data Services using ASP.NET Ajax Library scripts and components. The steps that will be discussed include:

  1. Creating an ADO.NET Data Service
  2. Loading Required Scripts
  3. Querying and Modifying Data

Step 1: Creating an ADO.NET Data Service

To create an ADO.NET Data Service you'll start by creating an Entity Framework model in Visual Studio. This can be done by right-clicking your project, selecting Add New Item and then choosing the ADO.NET Entity Data Model from the available templates (see Figure 1).

Image

Figure 1. Creating an Entity Framework model in Visual Studio.

From there the tables, views and stored procedures that should be exposed can be added to the entity model using the wizard. Once the Entity Framework model is available right-click on the project and select Add New Item again. Select the ADO.NET Data Service template and give the service a name as shown in Figure 2.

Image

Figure 2. Creating an ADO.NET Data Service in Visual Studio.

Once the ADO.NET Data Service class is displayed modify the DataService base class to reference the Entity Framework model created previously. The following example assigns the NorthwindEntities model to the service and allows all entities within the model to be accessed and modified by using the SetEntitySetAccessRule method. Note that the access level can be defined for each entity if desired to prevent specific entities from being changed.



public class CustomerAdoNetService : DataService<NorthwindEntities> { // This method is called only once to initialize service-wide policies. public static void InitializeService(IDataServiceConfiguration config) {

config.SetEntitySetAccessRule("*", EntitySetRights.All); //config.UseVerboseErrors = true; // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All); } }


Step 2: Loading Required Scripts

Now that the ADO.NET Data Service is available to use an ASP.NET or HTML page can be added to the project. In order to allow data to be displayed and modified the scripts shown in Figure 3 will need to be referenced. Fortunately, these scripts can be loaded quite easily by using the Script Loader.

Image

Figure 3. Scripts used to display and modify data exposed by an ADO.NET Data Service.

To load the scripts shown in Figure 3 the following Script Loader code can be used:

Sys.require([Sys.components.dataView, Sys.components.adoNetDataContext]);

The script loader will automatically handle loading all of the script dependencies needed by the DataView and AdoNetDataContext components based upon dependencies defined in Start.js.

Step 3: Querying and Modifying Data

Once the scripts are available an instance of the DataView and AdoNetDataContext components can be created. The AdoNetDataContext component is used to interact with the service and track data objects that are bound to controls in a page. This includes tracking any changes that are made to the data objects such as new objects being added, objects being deleted or object property values being changed. The DataView component acts as a data container and can be used to bind data returned from an ADO.NET Data Service to one or more client-side templates.

The following code demonstrates how to create a new AdoNetDataContext component:



// Create ADO.NET Data Context var dataContext = Sys.create.adoNetDataContext({ serviceUri: "Services/CustomerAdoNetService.svc" });


Once the AdoNetDataContext component is created it can be fed to the dataProvider property of the DataView. This allows the DataView to handle binding data to templates while the AdoNetDataContext monitors changes that are made to the data. An example of assigning the AdoNetDataContext component to a DataView instance is shown next:



// Create master view var master = Sys.create.dataView("#ShippersView", { dataProvider: dataContext, fetchOperation: "Shippers", fetchParameters: {'$top':10}, autoFetch: true, itemRendered: shipperRendered });

function shipperRendered(dataView, ctx) { Sys.setCommand(Sys.get("li", ctx), "select"); Sys.bind(Sys.get("li", ctx), "innerHTML", ctx.dataItem, "CompanyName"); }


This code binds the DataView component to a template with an ID of ShippersView, assigns the AdoNetDataContext as the data provider and defines the ADO.NET Data Service operation that should be called ("Shippers" in this example). The fetchParameter property is used to define a parameter that is passed to the service to control how many records are returned. The shipperRendered function handles binding each row of data to an <li> element defined in the template shown next and also raises an event as the user clicks an item.

<div id="ShippersView" class="sys-template">
    <div>
        <li style="cursor:pointer;" />
        <span />
    </div>
</div>


As users click one of the bound values an editable view of the data can be shown to allow them to make modifications. This can be done by creating a new DataView object and then binding it to the selected value of the parent DataView object shown earlier:



// Create detail view var detail = Sys.create.dataView("#DetailView", { itemRendered: detailRendered });

// Bind master/detail Sys.bind(detail, "data", master, "selectedData");

//Bind the detail view data to an input control to allow edits to be made function detailRendered(dataView, ctx) { Sys.bind(Sys.get("input", ctx), "value", ctx.dataItem, "CompanyName"); }


The template that the detail DataView is bound to follows:

<div id="DetailView" class="sys-template">
    Contact Name:
    <br />
    <input />
    
    <br /><br />
</div>


Once the user clicks a Save Changes button the AdoNetDataContext component can submit any changed records to the ADO.NET Data Service for processing. The code to attach a click event handler to a save button and call the service is shown next. Notice that the changes are submitted to the service by calling the AdoNetDataContext component's saveChanges function.



// Handle button click $addHandler(Sys.get("#btnSaveChanges"), "click", function () { dataContext.saveChanges(function () { alert("Changes Saved!"); }); });


The complete code for a page that consumes and modifies data exposed by an ADO.NET Data Service is shown next:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Read/Write Data Access</title>
    
    <script src="http://ajax.microsoft.com/ajax/beta/0911/Start.js" type="text/javascript"></script>
    <script type="text/javascript">

Sys.require([Sys.components.dataView, Sys.components.dataContext], function () {

// Create ADO.NET Data Context var dataContext = Sys.create.adoNetDataContext({ serviceUri: "Services/CustomerAdoNetService.svc" });

// Create master view var master = Sys.create.dataView("#ShippersView", { dataProvider: dataContext, fetchOperation: "Shippers", fetchParameters: {'$top':10}, autoFetch: true, itemRendered: shipperRendered });

// Create detail view var detail = Sys.create.dataView("#DetailView", { itemRendered: detailRendered });

// Bind master/detail Sys.bind(detail, "data", master, "selectedData");

// Handle button click $addHandler(Sys.get("#btnSaveChanges"), "click", function () { dataContext.saveChanges(function () { alert("Changes Saved!"); }); }); });

function shipperRendered(dataView, ctx) { Sys.setCommand(Sys.get("li", ctx), "select"); Sys.bind(Sys.get("li", ctx), "innerHTML", ctx.dataItem, "CompanyName"); }

function detailRendered(dataView, ctx) { Sys.bind(Sys.get("input", ctx), "value", ctx.dataItem, "CompanyName"); }

</script>

</head> <body>

<div id="ShippersView" class="sys-template"> <div> <li style="cursor:pointer;" /> <span /> </div> </div>

<br style="clear:both" />

<div id="DetailView" class="sys-template"> Contact Name: <br /> <input /> <br /><br /> </div>

<button id="btnSaveChanges">Save Changes</button>

</body> </html>