This article is from a talk I did for the Kansas City .net user group.
It will show you how to use the AJAX.net library written by
Michael Schwarz.
Initial Setup:
1) Download dll from http://ajaxpro.info
2) Open Visual Studio and create a new web application
3) Add a reference to the AJAX.net dll
4) Modify your web.config to include:
<system.web>
<httpHandlers>
<add verb="POST,GET" path="ajax/*.ashx" type="Ajax.PageHandlerFactory, Ajax"/>
</httpHandlers>
</system.web>
|
Now that we have the AJAX.net library ready to go.
We can create a simple web page to use it. We will tell the AJAX
utility that we have a class we want registered and we will mark our
functions with AJAXmethod attributes so the AJAX library can handle the
dirty work. The AJAX library will create .ashx files under the hood
that will post data back to the server without doing a full page refresh.
We will show a simple server clock application and a web page that
communicates with the Flickr API.
Demo 1
Automatically updating clock from server -
http://timhibbard.com/demo/ajaxdemo1.aspx
ASP .net code:
Partial Class AjaxDemo1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'tell the ajax utility to listen for requests
'from this class
Ajax.Utility.RegisterTypeForAjax(GetType(AjaxDemo1))
End Sub
<Ajax.AjaxMethod()> _
Public Function GetTimeFromServer() As String
Try
'return the current time from the server
Return Now.ToString
Catch ex As Exception
Return ex.ToString
End Try
End Function
End Class
|
HTML Code:
<body>
<form id="form1" runat="server">
<div>
<input id="btnStartTimer" type="button" value="Get .Net Time" onclick="startTimer();" />
<input id="btnStopTimer" type="button" value="Stop Timer" onclick="stopTimer();" disabled="disabled" />
<br /><br />
<div id="timeDiv" style="font-size:xx-large; font-weight:bold"></div>
</div>
</form>
</body>
<script type="text/javascript">
//stores id of our timer
var intervalID;
function startTimer()
{
//call the getDotNetTime function every second
//(1000 milliseconds)
//store the id of the timer in intervalID
//so we can turn it off later
intervalID = setInterval("getDotNetTime();",1000);
//disable the Start Timer button
document.getElementById("btnStartTimer").disabled = true;
//enable the Stop Timer button
document.getElementById("btnStopTimer").disabled = false;
}
function stopTimer()
{
//stop the timer
clearInterval(intervalID);
//enable the Start Timer button
document.getElementById("btnStartTimer").disabled = false;
//disable the Stop Timer button
document.getElementById("btnStopTimer").disabled = true;
}
//the function called by the timer
function getDotNetTime()
{
//go to the server...get the time and
//call getDotNetTime_callback when done
AjaxDemo1.GetTimeFromServer(getDotNetTime_callback);
}
function getDotNetTime_callback(response)
{
//put the response.value in the div
document.getElementById("timeDiv").innerHTML = response.value;
}
</script>
|
Demo 2
Get the 3 newest pictures submitted to Flickr.
Flickr has a web API that
allows us to get data without actually visiting the web site.
They make xml files available that are updated as people add or change pictures.
I created a flickr class that reads the xml with a XMLTextReader. You can
see this demo in action at
http://timhibbard.com/demo/ajaxdemo2.aspx
Flickr class:
Imports Microsoft.VisualBasic
Imports System.Xml
<Serializable()> _
Public Class Flickr
Private _pix As New FlickrCollection(Of FlickrItem)
Public Property Pix() As FlickrCollection(Of FlickrItem)
Get
Return _pix
End Get
Set(ByVal value As FlickrCollection(Of FlickrItem))
_pix = value
End Set
End Property
Public Sub New(ByVal FlickrURL As String)
Try
Dim xRead As New XmlTextReader(FlickrURL)
xRead.ReadToFollowing("photos")
Do While xRead.Read = True
If xRead.IsStartElement = True Then
If xRead.Name = "photo" Then
Dim pic As New FlickrItem
pic.ID = xRead.GetAttribute("id")
pic.Secret = xRead.GetAttribute("secret")
pic.Server = xRead.GetAttribute("server")
pic.Title = xRead.GetAttribute("title")
_pix.Add(pic)
End If
End If
Loop
Catch ex As Exception
End Try
End Sub
End Class
<Serializable()> _
Public Class FlickrItem
Private _id As String
Private _secret As String
Private _server As String
Private _title As String
Public Property ID() As String
Get
Return _id
End Get
Set(ByVal value As String)
_id = value
End Set
End Property
Public Property Secret() As String
Get
Return _secret
End Get
Set(ByVal value As String)
_secret = value
End Set
End Property
Public Property Server() As String
Get
Return _server
End Get
Set(ByVal value As String)
_server = value
End Set
End Property
Public Property Title() As String
Get
Return _title
End Get
Set(ByVal value As String)
_title = value
End Set
End Property
Public ReadOnly Property ImageURL() As String
Get
Dim RV As String
RV = "http://static.flickr.com/" & _server & "/" & _id & "_" & _secret & ".jpg"
Return RV
End Get
End Property
Public Sub New(ByVal PicID As String, ByVal PicSecret As String, ByVal ServerID As String, ByVal PicTitle As String)
MyBase.New()
_id = PicID
_secret = PicSecret
_server = ServerID
_title = PicTitle
End Sub
Public Sub New()
MyBase.New()
End Sub
End Class
<Serializable()> _
Public Class FlickrCollection(Of itemType)
Inherits CollectionBase
Public Sub New()
MyBase.New()
End Sub
Default Public Property Item(ByVal index As Integer) As itemType
Get
Return CType(MyBase.List(index), itemType)
End Get
Set(ByVal value As itemType)
MyBase.List(index) = value
End Set
End Property
Public Function Add(ByVal item As itemType) As Integer
Return MyBase.List.Add(item)
End Function
End Class
|
ASP.net code that consumes the Flickr
class:
Partial Class AjaxDemo2
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'tell the ajax utility to listen for requests
'from this class
Ajax.Utility.RegisterTypeForAjax(GetType(AjaxDemo2))
End Sub
<Ajax.AjaxMethod()> _
Public Function getFlickr() As String
Try
'declare our string that will contain
'html code
Dim rv As String = "<br>"
'create our flickr class
Dim myFlick As New Flickr("http://www.flickr.com/services/rest/?api_key=31bd33dc0c54fd8c8efc7c7a4ab0be15&method=flickr.photos.getRecent&per_page=3")
'iterate through each object
Dim item As New FlickrItem
For Each item In myFlick.Pix
'write the html to our return string
rv += item.Title & "<br />"
rv += "<img src='" & item.ImageURL & "' alt='flickr image' /><br /><br />"
Next
'send the string to the ajax callback function
Return rv
Catch ex As Exception
Return ex.ToString
End Try
End Function
End Class
|
HTML code:
<body>
<form id="form1" runat="server">
<div>
<input id="btnStartTimer" type="button" value="Get Recent Flickr" onclick="startTimer();" />
<input id="btnStopTimer" type="button" value="Stop Timer" onclick="stopTimer();" disabled="disabled" />
<br /><br />
<div id="flickr"></div>
</div>
</form>
</body>
<script type="text/javascript">
//stores id of our timer
var intervalID;
function startTimer()
{
//call the getFlickr function every 7 seconds
//store the id of the timer in intervalID
//so we can turn it off later
intervalID = setInterval("getFlickr();",7000);
//disable the Start Timer button
document.getElementById("btnStartTimer").disabled = true;
//enable the Stop Timer button
document.getElementById("btnStopTimer").disabled = false;
//call the function now so we don't have to wait
getFlickr();
}
function stopTimer()
{
//stop the timer
clearInterval(intervalID);
//enable the Start Timer button
document.getElementById("btnStartTimer").disabled = false;
//disable the Stop Timer button
document.getElementById("btnStopTimer").disabled = true;
}
function getFlickr()
{
//get the 3 newest pictures on flickr
//call getFlickr_callback when done
AjaxDemo2.getFlickr(getFlickr_callback);
}
function getFlickr_callback(response)
{
//put the returned HTML code in "flickr" div
document.getElementById("flickr").innerHTML = response.value;
}
</script>
|
The next demo will show how to incorporate
data from the Where's Tim API into Google Maps. First you will need to
sign up for a Google Maps key. We will consume the Where's Tim web
service, display it on a map, and also show my history for a day.
In Visual Studio, we will add our web references.
1)
http://timhibbard.com/webservices/engraphgps/engraph.asmx - WSWheresTim
2) http://maps.livewave.net/api.asmx
- WSLiveWave
3)
http://www.engraph.com/webservices/engraphgps/gps.asmx - WSCarl
ASP.net Code:
Partial Class AjaxDemo3
Inherits System.Web.UI.Page
Protected Sub form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles form1.Load
'tell the ajax utility to listen for requests
'from this class
Ajax.Utility.RegisterTypeForAjax(GetType(AjaxDemo3))
End Sub
<Ajax.AjaxMethod()> _
Public Function GetTimsLocation() As WSWheresTim.GPSData
Try
'declare a new object to talk to the
'web service
Dim ws As New WSWheresTim.EnGraphGPS
'return a serializable object that
'has information about my current location
Return ws.GetTimsLocation
Catch ex As Exception
Return Nothing
End Try
End Function
<Ajax.AjaxMethod()> _
Public Function GetLiveWavesLocation() As WSLiveWave.GPSData
Try
Dim ws As New WSLiveWave.api
Return ws.GetLocation
Catch ex As Exception
Return Nothing
End Try
End Function
<Ajax.AjaxMethod()> _
Public Function GetCarlsLocation() As WSCarl.GPSData
Try
Dim ws As New WSCarl.gps
Return ws.GetLocation
Catch ex As Exception
Return Nothing
End Try
End Function
<Ajax.AjaxMethod()> _
Public Function GetHistory() As HistoryObject()
Try
'declare a new object to talk to the
'web service
Dim ws As New WSWheresTim.EnGraphGPS
'get the history for 06/03/2006
Dim History() As WSWheresTim.GPSData = ws.GetTimsHistory("06/03/2006")
'temp storage for our objects
Dim tmpAL As New ArrayList
Dim intX As Integer
'iterate through each object
'placing them in our temp arraylist
For intX = 0 To History.GetUpperBound(0)
tmpAL.Add(New HistoryObject(History(intX)))
Next
'declare a new array of history objects
'that is the size of our arraylist
Dim RV(tmpAL.Count - 1) As HistoryObject
'copy the contents of the arraylist
'to our return value
tmpAL.CopyTo(RV)
'send the history array to the
'ajax callback function
Return RV
Catch ex As Exception
'something didn't work
'send an empty object back
Return Nothing
End Try
End Function
End Class
<Serializable()> _
Public Class HistoryObject
Private _gpsData As WSWheresTim.GPSData
Public Property GPSData() As WSWheresTim.GPSData
Get
Return _gpsData
End Get
Set(ByVal value As WSWheresTim.GPSData)
_gpsData = value
End Set
End Property
'returns the html that will go in the
'infowindowHTML
Public ReadOnly Property BalloonText() As String
Get
Dim rv As String = "<div style=white-space:nowrap;>"
rv += _gpsData.Since.AddHours(-5) & "<br/><br/>"
rv += _gpsData.Speed & " MPH<br /><br />"
rv += _gpsData.Place
Return rv
End Get
End Property
Public Sub New(ByVal GPSData As WSWheresTim.GPSData)
_gpsData = GPSData
End Sub
End Class
|
HTML:
<head runat="server">
<title>KC .NET UG - Google Maps with AJAX.net</title>
<style type="text/css">
v\:* { BEHAVIOR: url(#default#VML) }
</style>
<script src="http://maps.google.com/maps?file=api&v=2&key="your key here" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td style="font-size:xx-large;width: 400px">
<a href="javascript:trackWho='tim';track();">Where's Tim</a><br />
<a href="javascript:trackWho='livewave';track();">Where's LiveWave</a><br />
<a href="javascript:trackWho='carl';track();">Where's Carl</a><br />
<a href="javascript:getHistory();">Show History</a>
</td>
<td>
<div id="waitDiv"></div>
</td>
</tr>
</table>
<div id="mapDiv" style="width:100%; height:600px"></div>
</div>
</form>
</body>
</html>
<script type="text/javascript">
var trackWho = "tim";
//create map object
var map = new GMap2(document.getElementById("mapDiv"));
//add zoom control
map.addControl(new GLargeMapControl());
//add map - salellite - hybrid toggle control
map.addControl(new GMapTypeControl());
//create a point object in kansas city
var point = new GLatLng(39.095962936305476,-94.89990234375);
//set map center at kansas city point object, zoom to level 4
map.setCenter(point,4);
function track()
{
//show progress bar control
setWait();
//figure out which ajax function to call based
//on the trackWho variable
if (trackWho == "tim")
{
AjaxDemo3.GetTimsLocation(track_callback);
}
if (trackWho == "livewave")
{
AjaxDemo3.GetLiveWavesLocation(track_callback);
}
if (trackWho == "carl")
{
AjaxDemo3.GetCarlsLocation(track_callback);
}
}
function track_callback(response)
{
//read the return value from asp
var gpsPoint = response.value;
//make sure we actually got an object
if (gpsPoint != null)
{
//clear any existing markerts
map.clearOverlays();
//create a GLatLng object from our object
var point = new GLatLng(gpsPoint.Lat,gpsPoint.Lon);
//create a marker to place on the map
var marker = new GMarker(point);
//add the marker to the map
map.addOverlay(marker);
//get object that defines the boundary of the map
var bounds = map.getBounds();
//check to see if the bounds object contains our new point
if (bounds.contains(point) == false)
{
//our point is out of the bounds
//so recenter the map on our point
map.setCenter(point);
}
}
//stop the wait animation
clearWait();
}
function getHistory()
{
//show progress bar control
setWait();
//get a history dataset from the server
//call getHistory_callback when done
AjaxDemo3.GetHistory(getHistory_callback);
}
function getHistory_callback(response)
{
//get our history dataset
var historyPoints = response.value;
//make sure the object contains data
if (historyPoints != null)
{
//remove any existing markers from map
map.clearOverlays();
//iterate through points
//only doing something with every fifth
for (var i = 0; i < (historyPoints.length); i = i + 5)
{
//create a new icon object to place on map
var icon = new GIcon();
//define the parameters of the icon
icon.image = "http://labs.google.com/ridefinder/images/mm_20_blue.png";
icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
icon.iconSize = new GSize(12, 20);
icon.shadowSize = new GSize(22, 20);
icon.iconAnchor = new GPoint(6, 20);
icon.infoWindowAnchor = new GPoint(5, 1);
//create a GLatLng object from our history object
var point = new GLatLng(historyPoints[i].GPSData.Lat, historyPoints[i].GPSData.Lon);
//create a marker with the new icon
var marker = createMarkerIcon(point,historyPoints[i].BalloonText,icon);
//add the marker to the map
map.addOverlay(marker)
}
try
{
//create a GLatLng object from our last point (first in history)
var lastPoint = new GLatLng(historyPoints[historyPoints.length - 1].GPSData.Lat,historyPoints[historyPoints.length - 1].GPSData.Lon)
//get a bounds object
var bounds = map.getBounds();
//look to see if our point is viewable on the map
if (bounds.contains(lastPoint) == false)
{
//we can't see the point, so recenter the map on it
map.setCenter(lastPoint);
}
}
catch (e)
{
//something bad happened...
}
}
//stop the waiting animation
clearWait();
}
//function that returns a marker object given
//a GLatLng object, Icon object and the HTML
//to be displayed in the InfoWindowHtml
function createMarkerIcon(point,html,icon)
{
//create a marker
var marker = new GMarker(point, icon);
//tell google maps to listen for clicks on this marker
GEvent.addListener(marker, "click", function()
{
//perform this function when the event is raised
marker.openInfoWindowHtml(html);
});
//return our marker object
return marker;
}
function setWait()
{
//start our wait animation progress bar
document.getElementById("waitDiv").innerHTML = "<img src='http://timhibbard.com/images/ajax/progressbar_long_green.gif' />"
}
function clearWait()
{
//clear the wait animation
document.getElementById("waitDiv").innerHTML = "";
}
</script>
|