Feeding the DataView control with data returned from a Web Service

Published Wed, Oct 28 2009 12:37

Until now, we’ve been using static data to feed all the DataView controls we’ve been using in the MS AJAX series. Today we’ll see how we can configure the control so that it automatically gets data returned from a web service call. To get things started, we’ll start by introducing the server side code for the WCF service:

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(
RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)] public class PeopleService { [OperationContract] [WebGet] public IEnumerable<Person> GetPeople() { var people = new List<Person> { new Person{ Name = "luis", Address = "fx"}, new Person{ Name = "john", Address = "lx"}, new Person{ Name = "peter", Address = "pt"} }; return people; } } [DataContract] public class Person { [DataMember(Name="name")] public String Name { get; set; } [DataMember(Name="address")] public String Address { get; set; } }

Yes, not the best code in the world, but don’t forget that I’m not interested in creating web service! What I want is to show you how to properly configure the DataView control to get data from a web service…

As you can see, PeopleService is a WCF service which has a single operation: GetPeople. This method returns a collection of Person instances (since I wanted to preserve JS naming conventions, I’ve used the DataMemberAttribute to customize the name of the properties used in JSON returned from the server).

And now we can proceed with the most important part: configuring the DataView for getting the data automatically from the server side. In this case, I’ve opted for using the declarative approach:

<head runat="server">
    <title></title>
  <script src="Scripts/MicrosoftAjax/start.debug.js" 
type="text/javascript">
</
script> <script type="text/javascript"> Sys.require([Sys.scripts.WebService,
Sys.components.dataView]); </script> </head> <body xmlns:sys="BLOCKED SCRIPTSys" xmlns:dv="BLOCKED SCRIPTSys.UI.DataView"> <div id="view" class="sys-template" sys:attach="dv" dv:autofetch="true" dv:httpverb="GET" dv:dataprovider="PeopleService.svc" dv:fetchoperation="GetPeople"> <div> <span>{{name}}</span>- <span>{{address}}</span> </div> </div>

We start by loading the JS files needed for communicating with the server and using the DataView control. Since we need to communicate with the server side through a remote web service method call, we need to get the base classes defined in the MicrosoftAjaxWebService.js file.

Configuring the DataView isn’t really hard since we only need to set a couple of properties:

  • autofetch: this property expects a Boolean. Setting it to true makes the DataView control fetch the data from the web service automatically during its initialization;
  • httpverb: you can use this property to set the type of HTTP method call which will be used for communicating with the server;
  • dataprovider: this property is used for setting the provider which will return the info that populates the DataView control. You can pass one of the following types to it: a reference to an object which implements the Sys.Data.IDataProvider interface (ex.: a DataContext object), a reference to a web service proxy or a string with the URI of the service. In this example, I’ve opted for using a string which identifies the URI of the web service (we’ll leave the other options for future posts);
  • fetchOperation: the name of the operation which returns the data. You’ll typically use this property when you pass a web service proxy to the DataView’s dataProvider property. In the previous snippet, I’ve opted for using it to set the name of the method (notice that this wasn’t really needed because I could have initialized the DataView’s dataProvider property with the complete path to the web service method – ie, “PeopleService.svc/GetPeople”).

Besides these properties, there are a still a couple of properties related with getting data from a remote provider:

  • fetchParameters: literal object with the parameters that should be passed for the remote service method;
  • timeout: you can use this property to set the timeout in milliseconds;
  • isFetching: read-only property which indicates if the control is performing a remote call for fetching the data;

When the DataView control is fetching data from a remote provider, you can abort that operation by invoking the abortFetch method. On the other hand, you can force a remote call by invoking the fetchData method. Calling this method starts a remote call and will automatically refresh the control with the new data that is returned from the provider.

Besides properties and methods, the control has a couple of events which you can handle:

  • fetchFailed: this event will be generated when the remote call fails;
  • fetchSucceeded: as you can probably guess, this event will be fired when the DataView control receives a successful response from the provider.

A fetchfailed handler receives three parameters:

  • a reference to the error returned from the server;
  • a custom user context object which might have been passed to the control;
  • a string (“fetchData”) which identifies the method that originated the handle call;

A fetchSucceeded handler also expects the same number of parameters as the ones that are passed to the fetchFailed handler: the main difference is that the first parameter references the data returned from the service.

And this should be enough for getting you started with getting data through remote calls. There’s still more to come, so stay tuned!

Filed under: ,

Comments

# william apken said on Wednesday, October 28, 2009 7:39 AM

Nice job as usual.

Thanks for the explaining that 1st parameter on fetchSucceeded was the data. I could not figure out how to get my hands on the data. I load the data with a AdoNetDataContext coming from Ado Net Data Services.

Are you going to address the fetchParameters?

orderby, $top, $filter, expand are a few I'm currently trying to battle through.

# luisabreu said on Wednesday, October 28, 2009 7:49 AM

Yes, I will. Getting to the $top parameters, etc will take more time though because I'll need to dig into ado.net data services...

# ASPInsiders said on Wednesday, October 28, 2009 10:31 AM

In the previous post , we’ve seen how we can configure the DataView control to get data returned from

# LA.NET [EN] said on Wednesday, October 28, 2009 10:38 AM

In the previous posts , we’ve seen how to configure the DataView control so that it gets the data from

# ASPInsiders said on Wednesday, October 28, 2009 11:37 AM

In the previous posts , we’ve seen how to configure the DataView control so that it gets the data from

# william apken said on Wednesday, October 28, 2009 11:17 PM

function createHtml(html) {

               var aux = document.createElement("div");

               aux.innerHTML = html;

               return aux.childNodes[0];

           }

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

           Sys.onReady(function() {

           var browseHtml = "<td>{{FirstName}}</td><td>{{LastName}}</td>";

           var editHtml = "<tr><td>{{City}}</td><td>{{State}}</td><td>{{Zip}}</td></tr>";

           /// create the browseTemplate

           templates.browseTemplate = new Sys.UI.Template(createHtml(browseHtml));

           /// create the editTemplate

           templates.editTemplate = new Sys.UI.Template(createHtml(editHtml));

The line below does not work when I call .set_itemTemplate on the dataview.

  var browseHtml = "<td>{{FirstName}}</td><td>{{LastName}}</td>";

or

  var browseHtml = "<tr><td>{{FirstName}}</td><td>{{LastName}}</td></tr>";

It does not complain when you create the template only when you call .set_itemTemplate.

If I do not try and set the template but allow the code in html to be the template it works fine.

<table>

                   <thead>

                     <tr>

                       <td>Name</td>

                       <td>Address</td>

                     </tr>

                   </thead>

                   <tbody id="view" class="sys-template">

                    <tr><td>{{FirstName}}</td><td>{{LastName}}</td><td>{{City}}</td></tr>

                   </tbody>    

                 </table>

The code above works fine.  What I'm not taking into consideration when trying to create and assign the template.

# LA.NET [EN] said on Monday, November 02, 2009 5:20 AM

Until now, we’ve met some of the basic features introduced by the DataContext component. As I’ve said

Leave a Comment

(required) 
(required) 
(optional)
(required) 
If you can't read this number refresh your screen
Enter the numbers above:  

Search

This Blog

Tags

Community

Archives

Syndication

Email Notifications

News




  • View Luis Abreu's profile on LinkedIn


    Follow me at Twitter

    My books

    Silverlight 4.0: Curso Completo

    ASP.NET 4.0: Curso Completo

    Portuguese LINQ book cover

    Portuguese ASP.NET 3.5 book cover

    Portuguese ASP.NET AJAX book cover

    Portuguese ASP.NET AJAX book cover