XtremeData
LANGUAGES: C# | JavaScript
TECHNOLOGIES: Web Services
Create Efficient UIs
WebService behaviors make it easy to call a service, pass it parameters, and integrate returned data into a DHTML page.
By Dan Wahlin
Web Services are touted for their ability to integrate distributed systems in a cross-platform and language-neutral manner. Their solid grounding in XML standards allows this type of integration to occur. However, Web Services also can play a large role in other environments such as corporate intranets even when distributed systems might not necessarily need to be integrated. By using Web Services, data can be pulled into a Web page dynamically to minimize page refreshes and give customers a more client-server look and feel.
You can accomplish this technique by tying into Web Services using the WebService behavior, which Microsoft provides for use with Internet Explorer (IE). This JavaScript file makes it easy to call a service, pass it parameters, and retrieve returned data that can be integrated into a page using Dynamic HTML (DHTML). You can download the latest version of the WebService behavior from http://msdn.microsoft.com/downloads/samples/internet/behaviors/library/webservice/default.asp.
In this article, I'll show you how to leverage the WebService behavior to tie into Web Services and allow users to update, insert, and delete data more efficiently through an intranet page using mainly JavaScript and DHTML.
What is the WebService Behavior?
The WebService behavior is a JavaScript file embedded in a Web page using specific IE behavior syntax. You need IE 5 or higher, so this technique is a strong candidate for use in intranet applications where you are certain IE is being used because Netscape, Opera, and other browsers don't support behaviors.
Behaviors are JavaScript files that have embedded XML metadata describing the different features they expose. The WebService behavior exposes its own object model with properties, methods, and events. The WebService behavior has these tags at the top of the file to help describe it:
VALUE="Microsoft
WebService Behavior 1.0.1.1120" /> NAME="onserviceavailable"/> Although a complete discussion of all of these features is
beyond the scope of this article, you will see how to leverage some of the more
important features. Currently, the behavior works with products that support
Web Services Description Language (WSDL) 1.1 such as the .NET Framework, SOAP
Toolkit, and Apache SOAP Web Services. You can find complete documentation for
the behavior at http://msdn.microsoft.com/workshop/author/webservice/webservice.asp. Use WebService Behavior ASP.NET
Pages The first thing that must be done to use the WebService
behavior in a Web page is to embed it using syntax similar to this: style="BEHAVIOR:url(Scripts/WebService.htc)"> The previous code relies on the behavior functionality
built into IE 5 and higher to identify the location of the JavaScript file that
will be used to call Web Services. As shown, this file has an extension of htc.
File loading occurs on the client rather than on the server. Once embedded, the behavior can be invoked and used to tie
into a WSDL 1.1-compliant Web Service using JavaScript code. This is
accomplished by referencing the embedded behavior id (webService in the
previous code) and calling its useService method: var webServicePath = "WebServices/CustomersWS.asmx?WSDL"; webService.useService(webServicePath,"wsSend"); The useService method accepts the path to the WSDL
file for the Web Service and a custom name used to reference the Web Service. A
"friendly" name of wsSend is assigned in this example. This name will be used
each time the Web Service at CustomersWS.asmx is called using the behavior. Although additional features are available, this is all
that is required to hook up the behavior to a Web Service. WebMethods - methods
found in a Web Service - can then be called using the behavior's callService
method, the behavior id, and the "friendly" name you assigned to the service.
Here's an example of how to call the GetCustomerData method of the
wsSend service: wsCallID = webService.wsSend.callService(onWSGetCustomerData, "GetCustomerData", customerID); This call passes a parameter named customerID to the
method for processing. If the method accepted additional parameters, you could
include them as well by separating them with commas. Once called, any data
returned from the GetCustomerData WebMethod is passed to an event
handler named onWSGetCustomerData where it is processed. I'll discuss
the code within this and other event handlers later in the article. Build a Customer Support App Now that you've seen the basics of wiring the WebService
behavior to a Web Service, let's build a customer support application that
users can use on an intranet to insert, update, and delete customer data
through the browser. By using the behavior, the Web page doesn't need to be
refreshed each time new data is viewed, which enhances the user experience
greatly because they can perform their duties quicker and in a more enjoyable
manner. Figure 1 shows the customer support application. The application loads the initial customer data into an
ASP.NET DataGrid Web Server control on the server side when the page
first loads. The DataGrid is put into a scrollable div block. I
initially used a DropDownList control to show the different customers,
but because the user needed to be able to see multiple columns simultaneously,
the scrollable div solution worked better. The code to create the DataGrid is shown in Figure
2. Notice that the div tag wrapping the DataGrid has a style attribute
that limits its height to 180 pixels and has its overflow property set
to "auto" in order to create a scrollable area for the DataGrid. CellSpacing="0" BorderWidth="0"
Cellpadding="0" Width="100%"
Runat="server" AutoGenerateColumns="False" > Font-Name="arial" /> DataField="ContactName" /> DataField="CompanyName" /> title="Edit Customer" onClick="GetCustomerData('<%# DataBinder.Eval( Container.DataItem,"CustomerID")%>')"> <%# DataBinder.Eval( Container.DataItem,"CustomerID")%>
Figure 1. You can use the WebService behavior to call Web Services from
ASP.NET pages. The customer support application allows users to select an
existing customer and then edit or delete their data. When a customer is
selected, the WebService behavior grabs the data, JavaScript, and DHMTL, then
handles adding the proper data into the page. This allows the data to be added
without refreshing the page.
Figure 2. In applications where multiple columns need to be displayed to a user in a scrollable area, you can embed a DataGrid within a scrollable div. The code shown in this figure demonstrates how to bind a DataGrid to a data source and place the resulting grid columns into a div that has its CSS overflow property set to auto (for auto scrolling).
Instead of linking the CustomerID column in the DataGrid (see Figure 1) to a different page or even the same page, the link calls a local JavaScript function named GetCustomerData (see the bold section in Figure 2), which fires up the WebService behavior embedded in the page using the techniques I described earlier. The GetCustomerData JavaScript method accepts the CustomerID value and passes this value to the WebService behavior, which in turn calls the actual GetCustomerData Web Service method:
function GetCustomerData(customerID) {
ChangeCursor("wait");
//Call actual Web Service using the WebService Behavior
wsCallID = webService.wsSend.callService(onWSGetCustomerData,
"GetCustomerData", customerID);
}
Back on the server, the GetCustomerData Web Service method simply queries a SQL Server database for the appropriate customer data and returns a DataSet to the caller:
[WebMethod]
public DataSet GetCustomerData(string customerID) {
string sql =
"SELECT * FROM CustomersWS WHERE CustomerID='" +
customerID + "'";
SqlConnection dataConn = new SqlConnection(connStr);
SqlDataAdapter adap = new SqlDataAdapter(sql,dataConn);
DataSet ds = new DataSet();
adap.Fill(ds,"CustomersWS");
return ds;
}
Once the call to the Web Service method completes, the onWSGetCustomerData event handler in the Web page's JavaScript is fired and the returned DataSet data is accessed. Because DataSets are returned as XML, you can load them on the client side into a DOMDocument object to access the nodes. The code in Figure 3 shows how to load the returned XML into a DOMDocument object.
function onWSGetCustomerData(result) {
if (result.error) {
//Pull the error information from the
//result.errorDetail properties
var xfaultcode = result.errorDetail.code;
var xfaultstring = result.errorDetail.string;
var xfaultsoap = result.errorDetail.raw;
alert("Error returned from Web Service: " +
xfaultcode + " " + xfaultstring);
} else if (!result.error) { //Access returned data
var returnData = new ActiveXObject("MSXML2.DOMDocument");
returnData.async = false;
//Assign data returned from the Web Service to
//the DOMDocument
returnData.documentElement = result.value;
BindCustomerData(returnData);
returnData = null;
}
ChangeCursor("default");
}
Figure 3. The onWSGetCustomerData client-side callback function is called when the GetCustomerData Web Service method completes. The Web Method returns a DataSet that is loaded into a DOMDocument object on the client side.
Once the DataSet data is loaded into the DOMDocument, a JavaScript method named BindCustomerData is called, which reads the XML and binds it to text-box controls on the page. You can accomplish this easily by walking through the DOM structure (see Figure 4).
function BindCustomerData(xmlData) {
document.all.spanMessage.innerText = "";
document.all.tblCustomerData.style.display = "block";
document.all.btnSubmitInsert.disabled = true;
document.all.btnSubmitUpdate.disabled = false;
document.all.btnSubmitDelete.disabled = false;
var customers =
xmlData.selectSingleNode("//CustomersWS");
if (customers != null) { //Make sure we found the node
for (var
i=0;i var childNode =
customers.childNodes(i); //Add each text node
value in the XML to the proper //textbox in the
HTML. if (document.all("dc"
+ childNode.nodeName)) { document.all("dc" + childNode.nodeName).value = childNode.text; } } } } Figure 4. XML data returned from calling a remote Web
Service can be bound to client-side controls by walking through a DOM structure
programmatically. The BindCustomerData method shown here accepts a DOMDocument
object as a parameter and binds the data within the object to controls on the
page. By clicking on a CustomerID link in the DataGrid,
users can display any customer's data quickly and easily without a round trip
to the Web server and the accompanying refresh, giving the user a more
client/server feel to the application. Performing an insert, update, or delete operation to the
customer data is accomplished in a similar manner by using the WebService
behavior. First, a JavaScript method is called, which creates an XML document
from the data in the different text boxes. This document is then passed to a
Web Service method named UpdateCustomerData using the WebService
behavior. UpdateCustomerData then parses the XML and performs the
appropriate update, insert, or delete operation on the database. By thinking creatively, you'll find you can use the
WebService behavior in many ways within your intranet to make the process of
working with data much more pleasant and efficient for users. Although one
potential example of using the behavior has been demonstrated in this article,
the sky's the limit - there are many other ways you can use the WebService
behavior to perform useful tasks. To see a live demo of the WebService behavior application
discussed in this article, visit the XML for ASP.NET Developer's Web site at http://www.xmlforasp.net/codeSection.aspx?csID=67. The files referenced in this article are available for
download. Dan Wahlin is president of Wahlin Consulting and founded the
XML for ASP.NET Developers Web site (http://www.xmlforasp.net),
which focuses on using XML and Web Services in Microsoft's .NET platform. He
also is a corporate trainer and speaker and teaches XML and ASP.NET training
courses around the United States. Dan co-authored Professional Windows DNA (Wrox), ASP.NET: Tips, Tutorials
and Code (Sams), and authored XML for ASP.NET Developers (Sams). E-mail Dan at mailto:[email protected]. Tell us what you think! Please send any comments about this
article to [email protected].
Please include the article title and author.