Lives: 30

Web.UI Navigation Controls and Web Services

Posted Tue Apr 1, 2008 @ 10:45 AM


It's been some time now since we first started introducing client-side integration with ASP.NET AJAX web services into our controls. The first foray was the ability of Grid to bind directly to JavaScript object arrays, allowing it to directly load JSON data returned from a web service, and continue running in client mode (see demo). The interest that this generated prompted the next big wave: Grid’s WebService running mode (see demo) and web service functionality in all the major navigation controls: TreeView, Menu, TabStrip, NavBar and ToolBar (see demo).

In the latest iteration of Web.UI (2008.1) we standardized client-side events relating to web service calls across this group of controls, and added the ability to pass custom data to and from the web services. Each *WebServiceRequest and *WebServiceResponse class now has a CustomParameter property.

In this blog post, I want to illustrate how this custom data can be bounced around using standard client-side and server-side properties and client events.

Take as an example a Menu control, pointed at an ASP.NET Web Service:

<ComponentArt:Menu runat="server" ID="Menu1"
  WebService="MyService"
  WebServiceMethod="GetItems"
  WebServiceCustomParameter="Blue"
  ... />

In the above example, we are telling Menu to call the WebMethod GetItems of the service MyService, and to set the initial value of its WebServiceCustomParameter to "Blue". When the Menu loads on the client, it will do just that. Let’s see how we can access the custom parameter in the web service:

[System.Web.Script.Services.ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class MyService : System.Web.Services.WebService
{
  [WebMethod]
  public MenuWebServiceResponse GetItems(MenuWebServiceRequest request)
  {
    // Create a response object.
    MenuWebServiceResponse response = new MenuWebServiceResponse();

    // For this example, we will only return one item,
    // with the Text matching the custom parameter given to us.
    MenuItem newItem = new MenuItem(); 
    newItem.Text = request.CustomParameter;
    response.AddItem(newItem);

    // We will also return some custom data from the server.
    // Let’s make it the current time.
    response.CustomParameter = DateTime.Now.ToString();

    // Send the data back.
    return response;
  }
}

When this Menu loads on the client, it will load up the web service data, which will result in a single menu item entitled "Blue". We can always re-load data from the client by calling Menu’s client-side loadFromWebService method. We can also change the WebServiceCustomParameter on the client before doing so. For example, the following JavaScript would result in the Menu reloading its data and ending up with a single item entitled "Red":

Menu1.set_webServiceCustomParameter('Red');
Menu1.loadFromWebService();

This mechanism should enable unlimited reloading of data for any navigation control based on custom data passed from the client. One last thing remains to be answered: how do we access that custom data (the server time) we sent back to the client from the web service? This is where client events come in. If we want access to this custom data, we’ll have to hook the WebServiceComplete client event:

<ComponentArt:Menu runat="server" ID="Menu1" ... >
  <ClientEvents>
    <WebServiceComplete EventHandler="Menu1_WebServiceComplete" />
  </ClientEvents>
</ComponentArt:Menu>

In the event handler, we can access the custom data through the event arguments parameter:

function Menu1_WebServiceComplete(sender, eventArgs)
{
  alert('Loaded items from web service, along with this custom data: ' +
    eventArgs.get_customData());
}

I hope that explains this exciting new functionality and that you find it as neat and useful as we do. Do let us know what you think and how we can build on this in the future.

Posted to Milos Glisic by milos

Posted on Tue Apr 1, 2008 @ 10:45 AM

Filed under: , ,

Comments

Posted on Tue Apr 1, 2008 @ 10:45 AM
Using webservices with the TreeView I was able to get what used to be an initial and incremental 250kb payload (using a different vendor's TreeView) down to a 100KB initial payload and 6KB incremental payloads. My client, who has been fielding upset calls from customers for the last 2 weeks due to the large page sizes, is quite pleased!
LDAdams
Posted on Tue Apr 1, 2008 @ 10:45 AM
Thanks Milos, you posted this about an hour after I was looking for information on the site about using these new features. Good work as it works great. Cheers, Luke
Posted on Tue Apr 1, 2008 @ 10:45 AM
Does it support ServerSide Template?
Posted on Tue Apr 1, 2008 @ 10:45 AM
Can hierarchical grids (multi gridlevel) be bound with json arrays that hold a nested data structure? Ex. Categories array, with each category having a products array. I could accomplish this by databinding the categories arraylist on the server side, and setting the appropriate datamember property. However on the call from the client side to a web method returning the same arraylist, the second level grids are lost. Timely help is appreciated.
Anonymous comments are not allowed. Click here to log in or create an account.

Copyright © 2010 ComponentArt, Inc. All rights reserved.