(Editor's note: The Google API can and has changed so be warned that the code in this article may need to be modified to account for any changes)
Introduction
This is the fourth article in a three article series examining a custom ASP.NET server control I developed to make using the Google Maps API easier for .NET developers. The focus of this article is to highlight the changes I made while porting the GMap
control from ASP.NET 1.1 to ASP.NET 2.0. If you're not familiar with the GMap
control, I highly recommend reading Part 1, Part 2, and Part 3 first. This article assumes you are familiar with the Google Maps API. You may see references throughout the article to "my control, my GoogleMaps control, my GMap
control, etc.". I did not create the Google Maps API, I merely created a wrapper for ASP.NET using C#, XML, and XSL.
The four things to be covered are:
ICallbackEventHandler
– Using the new built-in callback features of ASP.NET 2.0. - Embedded script files – Put your custom JavaScript right into the assembly.
- Generics – Create strongly typed collections with one line of code.
- The new web.config – Some new areas of the configuration file.
This code was developed and tested using Visual Studio 2005 Beta 2. I have not tested nor can I guarantee that that code will work in another version/build of Visual Studio.
ICallbackEventHandler
In the ASP.NET 1.1 version of the GMap
control, I had to do a lot of extra work to make client callbacks function properly with ASP.NET pages. With .NET 2.0, Microsoft has made using client callbacks as easy as using regular server-side events.
The code below shows the RaiseCallbackEvent()
method. The only difference between this and the older version (RaisePostbackEvent()
) is the absence of the CallbackHelper.Write()
and CallbackHelper.HandleError()
calls. ASP.NET takes care of all of the plumbing and all of the client side JavaScript for us.
public string RaiseCallbackEvent(string eventArgument)
{
string[] ea = eventArgument.Split('|');
string[] args = null;
GPointEventArgs pea = null;
string evt = ea[0];
string retVal = String.Empty;
switch (evt)
{
case "GMap_Click":
args = ea[1].Split(',');
pea = new GPointEventArgs(float.Parse(args[0]), float.Parse(args[1]), this);
retVal = this.OnClick(pea);
break;
case "GMarker_Click":
args = ea[1].Split(',');
GPoint gp = new GPoint(float.Parse(args[0]), float.Parse(args[1]));
GMarker gm = new GMarker(gp, args[2]);
pea = new GPointEventArgs(gp, gm);
retVal = this.OnMarkerClick(pea);
break;
case "GMap_MoveStart":
args = ea[1].Split(',');
pea = new GPointEventArgs(float.Parse(args[0]), float.Parse(args[1]));
retVal = this.OnMoveStart(pea);
break;
case "GMap_MoveEnd":
args = ea[1].Split(',');
pea = new GPointEventArgs(float.Parse(args[0]), float.Parse(args[1]));
retVal = this.OnMoveEnd(pea);
break;
case "GMap_Zoom":
args = ea[1].Split(',');
GMapZoomEventArgs zea = new GMapZoomEventArgs(int.Parse(args[0]),
int.Parse(args[1]));
retVal = this.OnZoom(zea);
break;
case "GMap_ClientLoad":
retVal = this.OnClientLoad();
break;
case "GMap_MapTypeChanged":
retVal = this.OnMapTypeChanged();
break;
default:
throw new System.Web.HttpException(
String.Format("Invalid GMap Event Sender: {0} Event: {1}", this.ID, evt));
}
return retVal;
}
Embedded Script Files
Another great feature of ASP.NET 2.0 is the ability to embed files into an assembly (JPEGs, GIFs, js files, XSL files, etc.) and reference them in your pages. This magic is courtesy of the new ClientScriptManager
. For more details on this process, read "Embedding Resources in ASP.NET 2.0 Assemblies" by Mark Hines. Version 1.1 of the GMap
control relied on the developer to place the proper client files (GMapX.js, GMap.xsl, and CallbackObject.js) in a folder of their web application. This folder had to be referenced in the web.config file. Any changes made to the control required updating the control assembly and possibly the three supporting files. As you can see, this could become a maintenance nightmare. With .NET 2.0, these files are now embedded in the assembly directly. No need to manage multiple files, everything is wrapped up nicely in the DLL file.
The code below found in AssemblyInfo.cs tells the framework that the two files GMapX.js and GMap.xsl can be found in the assembly.
[assembly: System.Web.UI.WebResource("WCPierce.Web.GMapX.js", "text/javascript")]
[assembly: System.Web.UI.WebResource("WCPierce.Web.GMap.xsl", "text/xml")]
Obtaining a reference to the files for use in the page's rendered HTML is a simple method call.
ClientScriptManager cs = Page.ClientScript;
cs.RegisterClientScriptInclude(GMap.ScriptName,
cs.GetWebResourceUrl(this.GetType(), "WCPierce.Web.GMapX.js"));
The resulting output on your page looks something like this:
<script
src="http://www.codeproject.com/WCPierceWeb/WebResource.axd?d=3ZY3jtwRvU5AI2&t=634837500"
type="text/javascript"></script>
<Generics>
If you plan on moving to .NET 2.0 and you haven't already, I strongly recommend learning about generics. Check out "Generics Explained" by zubinraj for a good overview on generics. For version 1.1 of the control, I used CodeSmith to generate a strongly-typed ArrayList
for overlays, icons, controls, and points. This resulted in thousands of lines of code for five classes. But that is the price you had to pay for a truly strongly-typed ArrayList
. Using generics, the code for GOverlays
is now seven (7) lines instead of 2,662.
using System;
namespace WCPierce.Web.UI.WebControls
{
[Serializable]
public class GOverlays : System.Collections.Generic.List<GOverlay> { }
}
Pretty amazing 'eh? Seven lines of code and I have a perfectly formed, strongly-typed ArrayList
waiting to do my bidding.
The New Web.Config
There are a lot of new features in Configuration for ASP.NET 2.0. For a complete look at the new features, check out "Managing Your ASP.NET Application". The main usage in GMap
2.0 is registering a custom control once in the web.config file and being able to use it throughout your application with full Intellisense. The blurb below shows a portion of the web.config file included in the code download.
<pages>
<controls>
<add namespace="WCPierce.Web.UI.WebControls"
assembly="WCPierce.Web" tagPrefix="wcp"/>
. . .
</controls>
</pages>
With this line added you can easily add a GMap
control to any page in your application like the code below. You also get full HTML Intellisense for free.
<wcp:GMap runat="server" id="gMap" Width="750px" Height="525px" />
Conclusion
This article was so short I'm almost embarrassed to call it an article. I wanted to keep it brief, and focus on the changes made to make the GMap
take advantage of ASP.NET 2.0. If you want full details on the creation of the GMap
control, check out Part 3 where I cover the code in depth. Until next time, Happy Mapping!