This is a fun and useful concept that is actually really very easy to implement. The recipe calls for two cups webservice, an ounce of AJAX ScriptManager, finished with a dash of javascript.
Note: Begin with an AJAX Enabled Website!
Let’s Start With the Webservice
Obviously, to work with AJAX Webservices you need to start with a webservice. You can use any webservice that you like depending on the application; for the purpose of this demonstration our objective will be to retrieve a list of employees and their job application (sort of).
Instead of working with SQL to retrieve the data, I am going to simulate this process and then write everything into XML format to make it easier to work with in javascript. Under normal conditions, I would be retrieving information from a database, otherwise the webservice would be a bit pointless.
Below is the pseudo-code to setup our mock webservice:
<WebMethod()> _ Public Function getData() As String Dim dt As New DataTable Dim dr As DataRow Dim dc As DataColumn dc = New DataColumn dc.ColumnName = "Name" dc.DataType = GetType(String) dt.Columns.Add(dc) dc = New DataColumn dc.ColumnName = "Occupation" dc.DataType = GetType(String) dt.Columns.Add(dc) dr = dt.NewRow() dr("Name") = "Nicholas B" dr("Occupation") = "Computer Geek" dt.Rows.Add(dr) dr = dt.NewRow() dr("Name") = "Logan B" dr("Occupation") = "Jon-boat Captain" dt.Rows.Add(dr) dr = dt.NewRow() dr("Name") = "Ben G" dr("Occupation") = "Aspiring Computer Geek" dt.Rows.Add(dr) dr = dt.NewRow() dr("Name") = "David M" dr("Occupation") = "Pool Shark" dt.Rows.Add(dr) dr = dt.NewRow() dr("Name") = "Eric V" dr("Occupation") = "Inventory Terminator" dt.Rows.Add(dr) Return getDataXML(dt) End Function Public Function getDataXML(ByVal dt As DataTable) As String Try If dt.Rows.Count > 0 Then Dim sb As New StringBuilder sb.Append("<?xml version=""1.0"" encoding=""iso-8859-1""?>") sb.Append("<crew>") Dim array(dt.Rows.Count - 1) As Double For i As Integer = 0 To dt.Rows.Count - 1 sb.Append("<person>") sb.Append("<name>" & dt.Rows(i).Item("Name") & "</name>") sb.Append("<occupation>" & dt.Rows(i).Item("Occupation") & "</occupation>") sb.Append("</person>") Next sb.Append("</crew>") Return sb.ToString() Else Return Nothing End If Catch ex As Exception Return Nothing End Try End Function
The getDataXML() function is just to help move the datatable format into XML in the schema that I want for this demo. The key here is that you have a webservice and it is doing something (in this case returning a list of employees in XML format).
A Secret Ingredient
There is one last secret ingredient that needs to go into your webservice. You need the following line above your webservice class declaration:
<System.Web.Script.Services.ScriptService()> _
This line enables the webservice to be called from javascript and is required.
A Bit of AJAX Script Manager
Next we need to register the script manager and script manager proxy. Take a look at the following code, which goes in the HTML:
<asp:ScriptManager ID="ScriptManager1" runat="server" /> <asp:ScriptManagerProxy id="ScriptManagerProxy1" runat="server"> <Services> <asp:ServiceReference Path="~/webservice_demo.asmx" /> </Services> <Scripts> <asp:ScriptReference Path="~/javascript_demo.js" /> </Scripts> </asp:ScriptManagerProxy> <input type="button" value="Get Data" onclick="getDataJS();" />
<div id=”crew”> </div>
“~/webservice_demo.asmx” is the location of my webservice file and ~/javascript_demo.js” is the location of my external javascript file (which we haven’t covered yet).
The input button is just going to be our trigger to execute the AJAX webservice call; this could be any event-based trigger. The div tag (crew) is just a container to hold our results when they are returned.
Our Dash of Javascript (Maybe a Bit More than a Dash)
//Get all locations from webservice getLocationInfoByUser() function getDataJS() { var ret = webservice_demo.getData(getDataJS_Complete, onError, onTimeout); return true; } function getDataJS_Complete(arg) { // code for IE if (window.ActiveXObject) { var doc=new ActiveXObject("Microsoft.XMLDOM"); doc.async="false"; doc.loadXML(arg); } // code for Mozilla, Firefox, Opera, etc. else { var parser=new DOMParser(); var doc=parser.parseFromString(arg,"text/xml"); } // documentElement always represents the root node var x=doc.documentElement; var htmlstring = ""; for(i=0;i<x.childNodes.length;i++) { var name = x.childNodes[i].childNodes[0].childNodes[0].nodeValue; var occupation = x.childNodes[i].childNodes[1].childNodes[0].nodeValue; htmlstring += "<p>" + name + " " + "(" + occupation + ")</p>"; } document.getElementById("crew").innerHTML = htmlstring; } function onError(arg) { alert("Error"); } function onTimeout(arg) { alert("Timeout"); }
Let’s walk through the javascript a bit. First, getDataJS() is being called from our button onclick event. It simply calls our proxy webservice. Notice, our webservice doesn’t have the additiona onComplete, onError, onTimeout parameters. These parameters were added by the proxy as all webservices being called through the AJAX Script Manager needs to account for errors, timeouts, and successes.
The next function, getDataJS_Complete() gets executed if a sucessful call to the webservice is made. The code that we added loops through the XML and builds a simple listing of the results returned. It then passes those results into a div we had on the page.
We’ve taken a pretty cheap way out of the error and timeout handling. You can get creative with what happens upon errors; this is pretty standard just to show there was a timeout or there was an error with the webservice.
Bon Apetit
So, without a whole lot of pain we’ve created an AJAX webservice that we can call in our webpages. Hope this helps!
Hey, I found this blog article while looking for help with fixing Microsoft Silverlight. I’ve recently switched internet browser from Safari to Firefox 3.2. After the change I seem to have a issue with loading websites that use Microsoft Silverlight. Everytime I go on a page that requires Microsoft Silverlight, my browser freezes and I get a “npctrl.dll” error. I can’t seem to find out how to fix the problem. Any aid getting Microsoft Silverlight to work is greatly appreciated! Thanks