Click here to monitor SSC
  • Av rating:
  • Total votes: 30
  • Total comments: 14
Djonatas Tenfen

Building an Airport Status Mashup with Silverlight and Bing Maps

15 July 2010

Djonatas Tenfen demonstrates, in fine detail, how to quickly and easily build a mashup Silverlight application to consume and manipulate multiple data sources, and plot airports' realtime status onto a map. He even supplies the project so you can try it for yourself.

In this article, I’ll show you how to use some of the features of Bing maps, and how to use the data Bing provides to build a Silverlight application to show the status of U.S. airports. I’ll break this project down into fine-grained steps so that you can see each aspect of it, and we’ll walk through the creation of the application from start to finish to get a thorough understanding of how this kind of application is put together. So, let’s get started!


Before we can actually start building the Silverlight application and doing cunning things with data, we need to set ourselves up to be able to use Bing’s services.


First of all, you need to register on the Bing developer site. Click on Create an AppID (in the top right-hand corner), and you’ll need to enter your LiveID (or create one if you don’t have one already), and then submit some basic information such as Application Name, Description, Company Name and email address. It’s worth remembering that despite the registration for the service, Bing is currently free.

Download the SDK

After completing registration, head back to the Bing developer site, log in, and click on Download the SDK. You’ll be directed to the Microsoft Download Center to get a copy of the SDK, which is currently on version 2.0. Simply download the kit and perform the installation as you would for any other SDK.

Creating the Application

After you’ve registered and downloaded the SDK, open Visual Studio 2010 and create a "Silverlight Application" project; in my example, I will name the application AirportStatus_BingMaps (as you can see in figure 1), and to facilitate the publication of the application I’ll create a Web Site from the "Silverlight Application" template, as recommended.

Figure 1. Creating the Silverlight Application project (click on the image for an enlarged view).

Referencing the Assemblies

Now that we have created the application, we’ll reference the Assemblies necessary to present the maps in the application.

To select the Assemblies, right-click on the AirportStatus_BingMaps Silverlight project, select "Add Concerning ...", select the Browse tab, and navigate to the C:\Program Files\Bing Maps Silverlight Control\V1\Libraries directory. Select the files Microsoft.Maps.MapControl.Common.dll and Microsoft.Maps.MapControl.dll, and don’t forget to confirm that the references have been added to your project correctly.

Creating the Map

Now that we've created the application and referenced the assemblies, we can create a map within the project. Inside the MainPage.xaml file, within the LayoutRoot grid and just below the line:

<Grid X:Name="LayoutRoot" Background="White">

  … add two columns into the grid, as listed below:


    <ColumnDefinition />

    <ColumnDefinition Width="200"/>


Now that we’ve added the columns (which will, in turn, determine the layout of our application) we’ll add the namespace that will reference Bing maps. Just above the same line in MainPage.xaml as before, reference the namespace using the syntax:


In the area reserved for the declaration of the XAML namespace, you should see the complete list of references:









Now that the assembly is referenced within our XAML, and basic layout of the application has been created, we can finally create the map. Just below the layout definition on the </ Grid.ColumnDefinitions> line, add the control (obviously, substituting “Your Bing Maps Key” as appropriate):

<bing:Map CredentialsProvider="Your Bing Maps Key" Mode="Aerial" x:Name="myMAP" />

This control has some properties which I’ll explain: First, it calls Bing the alias for the namespace, and uses this alias to call the controls contained within this namespace, followed by the alias name (myMAP). The control that we are calling in the current situation is the Map, which is followed by the CredentialsProvider property, where you need to input the registry key that your were emailed when registering with the Bing Developer Center. The second property, Mode, indicates what type of map is loaded (Road or Aerial view), and finally we have the property that indicates the name of control, as mentioned a moment ago. To verify your coding, run the application, and the result should look like Figure 2.

Figure 2. The basic Silverlight application, calling a map from Bing (click on the image for an enlarged view).

Building the Airport Class

To improve the function of our currently basic application, let's create a class that will contain all (or almost all) U.S. airports with their current status. To create the class, just hit Shift + Alt + C, select Class from the Add New Item window, and change the class name to "Airport" and the file name to Airport.cs. Now that the class is created, add the class properties as listed below:

public class Airport
public string ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Location Location { get; set; }

Note that the Location property does not have a primitive type, so the type is resolved using the Microsoft.Maps.MapControl which we added in the header file.

Loading the XML file

Luckily for you, the details of the names and airport codes of the U.S. airports are contained in an XML file which I’ve already created, which can be downloaded from here. This file contains almost all U.S. airports, although you should note that it only contains their airport codes and names; the exact location of the airports identified will be found using a WCF service from Bing. To add the file to the project, you can simply download it and save it directly into the project.

Bing’s WCF Reference Service

To consume the services of Bing maps, right-click on the AirportStatus_BingMaps project and click on Add Service and, in the Address property, enter:

This service is responsible for conducting searches of locations and drawing routes, among other things. More details of the service and the Bing SDK can be found on Microsoft’s interactive Maps Control SDK demonstration site. After entering the address into the application, click on GO, wait while the service is loaded, and you should eventually see something like figure 3, with the service referenced and loaded. For the rest of the article, I’ll simply refer to the service as "Geoservices".

Figure 3. Bing’s WCF Geoservices, references and loaded.

Reading Airports.XML and Consuming the WCF Service

Now that we have the service configured and the list of airports, we need to use the data we have to find the position of each airport. So, go back to the MainPage.xaml file and, just below the <Bing: Map CredentialsProv ... >line, add the following code:

    <StackPanel Grid.Column="2" Orientation="Vertical">

      <Button Content="Install" x:Name="btnInstall" Height="25"/>

      <ListBox x:Name="lstbAirports" Margin="10,0,0,0">



            <StackPanel Orientation="Horizontal">

              <TextBlock Text="{Binding ID}" />

              <TextBlock Text=" - " />

              <TextBlock Text="{Binding Name}" />







In this code I am simply creating a container called StackPanel and putting some controls around it; namely a Button and a ListBox. Note that we’ve changed the DataTemplate of the Listbox so that the information is consistently being displayed as "ID - Name", and note also that the XAML coding part of this project is finished!
Next, we’ll open MainPage.xaml.cs and create a method that will read the Airports.xml file and then search for each airports’ location through the Bing Geoservices. First add the references for the Microsoft.Maps.MapControl and System.Xml.Linq namespaces, and then create the following two private properties in MainPage.xaml.cs (I will not use the MVVM pattern in this article):

private geoService.GeocodeServiceClient _geoservice;
private geoService.GeocodeRequest _geocodeRequest;&#160;
private List<Airport> Airports;

These properties will help us to consume the Bing services; the _geoservice is just a reference to the Bing service, and _geocodeRequest is where we will create the credentials that will be sent with the request that we’ll generate in just a moment. The third property is a generic list of type Airport, which will contain the list of airports for as long as the application is live.

Now that the ancillary properties have been generated, we can create a GetAirports method to read the Airport.xml file and transform each entry into an Airport object to be added to the Airports list. To add the necessary System.Xml.Linq assembly to AirportStatus_BingMaps, you follow the same process as when we added the assemblies at the start of the article, although this time you’ll need to navigate to the C:\Program Files\Microsoft SDKs\Silverlight\v4.0\Libraries Client\ directory and select the System.Xml.Linq.dll file (don’t forget to confirm that the reference is added correctly). Now we can add the following code to the MainPage.xaml.cs file:

public void GetAirports()
        XDocument doc
= XDocument.Load("Airports.xml");
_geocodeRequest = new geoService.GeocodeRequest();
_geocodeRequest.Credentials = new Credentials();
_geocodeRequest.Credentials.ApplicationId = ((ApplicationIdCredentialsProvider)myMAP.CredentialsProvider).ApplicationId;
foreach (var item in doc.Elements("Airports").Elements("Airport").ToList())
          var airport
= new Airport();
airport.ID = item.Attributes("id").FirstOrDefault().Value;
airport.Name = item.Attributes("name").FirstOrDefault().Value;

Don’t forget to add the Microsoft.Maps.MapControl and System.Xml.Linq namespaces, or obviously none of this will work.

Here’s what’s happening in this method:

  • It first creates a local variable of type XDocument that will read the XML file through LinqToXML,
  • A private property receives an instance of the previously-created GeocodeRequest class,
  • An instance of the Credentials class is created, which will load the credentials that we mentioned at the start of the article,
  • The _geocodeRequest.Credentials.ApplicationId property is altered, receiving the ApplicationId  in the myMAP control via XAML,
  • A command-type foreach loop is created, which will traverse the entire airports.xml file and, for each Airport Node, create an instance of Airports and add it to the private property of type list<Airport> “Airports".

Finally, note that the last foreach line is calling another method, which is responsible for making the location search work; this Search method is described below:

public void Search(string id)
if (_geoservice == null)
= new geoService.GeocodeServiceClient(
_geoservice.GeocodeCompleted += new EventHandler<
= id;

The method first confirms that the Geoservice has no other instances running, so as to avoid unnecessary code and unnecessary memory consumption. If the result of this check is null, then the method creates a new instance of the service through the configuration interface of the endpoint, and then adds an EventHandler to the GeocodeCompleted event, which runs at the end of the WebService search, which is an asynchronous WCF service call from the Silverlight application.

Remember, in Silverlight you can only make calls to asynchronous services.

Upon validation and instantiation of the service, we indicate the search query which, in our example, will be the ID of the airport, and then we have an asynchronous call to the method of the newly-created and referenced GeocodeAsync service. Now, we are running the service asynchronously, but we know that the returning results will have to eventually be addressed in order to implement the GeocodeCompleted event, as the code below illustrates:

private void service_GeocodeCompleted(object sender, geoService.GeocodeCompletedEventArgs e)
if (e.Result.ResponseSummary.StatusCode ==
if (e.Result.Results[0].EntityType == "Airport")
            var airport
= Airports.Where(p => p.Name ==
airport.Location = e.Result.Results[0].Locations[0];

As you can see, this method is handling the return from the GeocodeCompleted service. Note that validation is performed first , confirming that the service returned successfully, and then we identify if the result is of the "Airport" type. Having performed these validations, we search through our pre-prepared list of airports to find an airport with the same name as the WebService returned (performed by the lambda expression created in the method). After finding the airport in the list, the Location property is just updated to the location obtained from the service. To test the application now, go to the MainPage class constructor and update the following code snippet:

public MainPage()
Airports = new List<Airport>();
lstbAirports.ItemsSource = Airports; uiElements

Now run the application and check that the result looks similar to Figure 4:

Figure 4. Running the application with Bing’s WCF Geoservice (click on the image for an enlarged view).

Locating and Marking Airports on the Map

Now that the Geoservice is up and running, and the map is being displayed, we can mark the location of airports on the map. First we'll create a private property named imageLayer with type MapLayer (private MapLayer imageLayer;), and then locate the GetAirports () method and added the following code to the beginning of the method, before we create a variable of type XDocument doc:

imageLayer MapLayer = new ();
myMAP.Children.Add (imageLayer);

Perhaps you’re wondering what this is? The first is a property receiving an instance of class type MapLayer, which is a kind of layer that can be created on the map and customized with some information, and we add this layer to the map through the Children property of myMAP. Next, we need to find the Search (string id) method and, just below the line:

_geoservice = new geoService.GeocodeServiceClient("BasicHttpBinding_IGeocodeService");

… we need to add an EventHandler for the GeocodeCompleted event, encoded in a similar way to _geoservce.GeocodeCompleted += new :


Tip:You can use the snippet functionality of Visual Studio in this instance; code to the equality operator and press tab twice, and Visual Studio will handle the creation the method and make the reference to the event.

The code that will be implemented in the _geoservice_GeocodeCompleted method, referenced by the GeocodeCompleted event, is as follows:

void _geoservice_GeocodeCompleted(object sender, geoService.GeocodeCompletedEventArgs e)
if (e.Result.ResponseSummary.StatusCode == geoService.ResponseStatusCode.Success &amp;&amp; e.Result.Results[0].EntityType == "Airport")
          Image img
= new Image();
img.Source = new BitmapImage(new Uri("Flag2_Green.png", UriKind.Relative));
img.Width = 20;
img.Height = 20;

imageLayer.AddChild(img, e.Result.Results[0].Locations[0]);
var airport = Airports.Where(p => p.Name == e.Result.Results[0].DisplayName)
airport.Location = e.Result.Results[0].Locations[0];

Before we continue, you need to add an image to the AirportStatus_BingMaps project through the "Add Existing Item" menu, and change the URI to the name of the image which you’ve added (in my case it was Flag2_Green.png), and ensure that this is reflected in  your method.

First we’re verifying the status of the returned results. If successful (i.e. the result is of type "Airport") and if the conditions are met, then the method creates an object of type Image, changes some of that object’s properties (such as the image source and size), and then adds the image to the customizable layer that was added to the map earlier. The second parameter of the method, AddChild, indicates the location on the map where the image should be positioned, which in our case is the position returned by the Geoservice airport search.

Next, the method finds the given airport using the description from my imported XML list, and then swaps the Location property in the file with the results from the service, so that we now know the correct position of each airport on the list.

Now that we’ve marked the map with the location of airports, we'll arrange it so that selecting an airport in the list on the right-hand side of the application will focus on that airport in the map. So, we return to the MainPage.xaml file and locate the lstbAirports ListBox control, and delegate an event for this control by modifying the code to get an XAML statement like this:

<ListBox x:Name="lstbAirports" Margin="10,0,0,0" SelectionChanged="lstbAirports_SelectionChanged">

Tip: use the NewEventHandler snippet of Visual Studio to create the method in MainPage.xaml.cs automatically.

Next, change the lstbAirports_SelectionChanged method to:

private void lstbAirports_SelectionChanged(object sender, SelectionChangedEventArgs e)
((lstbAirports.SelectedItem as Airport).Location, 14);

What we did in this method is just to change the SetView property of the map to the location of the airport selected in the list, and the second property is simple the level of zoom.

Now let's create a new property called uiElements that will be of type Dictionary<Airport, UIElement>; this will map an image to the airport to facilitate the next  step, where we’ll return the service status of the airport. After declaring the Dictionary variable, go to the constructor and instantiate the property immediately after the InitializeComponent () method:

uiElements = new Dictionary<Airport,UIElement>();

Go to the _geoservice_GeocodeCompleted method and immediately after the line:

airport.Location e.Result.Results = [0] . Locations [0];

… Include this code snippet:

if (!uiElements.ContainsKey(Airports.Where(p => p.Name == e.Result.Results[0].DisplayName).FirstOrDefault()))
uiElements.Add(airport, img);

In this snippet we discover whether the airport is on the list of UI elements and, if it’s not, we add the image and airport to the new dictionary, as this will be used in the status mapping later on. Let's see what the application looks like at this point:

Figure 5. The entire list of airports with their locations displayed on the map (click on the image for an enlarged view).

Figure 6. Selecting Las Vegas airport and automatically having the map focus on it (click on the image for an enlarged view).

Out Of Browser

Now that the application nearly 100% complete, we’ll enable it to exist Out Of Browser. if you look at the layout of the application, you’ll see the Install button in the top right-hand corner. That button is going to install the application on the local machine, so that we can consume an RSS feed without going through security policies and get the desired result: the current status of the airports.

To do this, open the project properties of AirportStatus_BingMaps, navigate to the Silverlight tab and check "Enable application running out of the browser". Next , click the Out-Of-Browser Settings button, check the "Require elevated trust When running outside the browser " option, and click OK.

Figure 7. Configuring the Silverlight application to run Out of Browser(click on the image for an enlarged view).

Now that the application is configured to run outside the browser, we close the project properties, go back to MainPage.xaml, and delegate the Install button’s click event:

<Button Content = "Install" x:="" Name = "btnInstall" Height = "25" Click = "btnInstall_Click" />

Now go to MainPage.xaml.cs and locate the btnInstall_Click method created by Visual Studio, and change the code to:

private void btnInstall_Click(object sender, RoutedEventArgs e)
if (Application.Current.InstallState != InstallState.Installed)

First a validation is performed by checking whether the application is installed or not and, if not, then the method performs the installation. When we start the application in the browser and click on "Install" we’ll see the following dialog:

Figure 8. Installing the application on your local machine.

If we click on Install, the application will then run on our machine as if it were a local executable.

Reading information about the status of airport RSS

Now that the application is running out of browser, it can access the RSS feed from and use it to find the current status of the US airports. First let's give MainPage.xaml.cs a way of cleaning the HTML that comes through the RSS feed:

private string ReplaceHTMLChars(string str)
        StringBuilder sb
= new StringBuilder(str);
sb.Replace("\n", string.Empty);
sb.Replace("<b>", string.Empty);
sb.Replace("</b>", string.Empty);
sb.Replace("<strong>", string.Empty);
sb.Replace("</strong>", string.Empty);
sb.Replace("<small>", string.Empty);
sb.Replace("</small>", string.Empty);
sb.Replace("<br />", "\n");
sb.Replace("<br>", "\n");
sb.Replace("<p>", "\n");
sb.Replace("/", "-");
sb.Replace("</p>", string.Empty);
return sb.ToString();

Now we’ll add another method that will request the appropriate RSS feeds:

private void GetDescription(string search)
        WebClient client
= new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(
string url = "" + search;
client.DownloadStringAsync(new Uri(url));

... and immediately below that, we’ll write a method for handling the return from the RSS feeds and adding the results to our map:

private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
if (e.Error == null)
          XDocument doc
= XDocument.Parse(e.Result);
var item = doc.Elements("rss").Elements("channel").Elements("item")
var airport = Airports.Where(p => p.ID == item.Element("title")
.Value.Substring(0, 3)).FirstOrDefault();
(uiElements[airport], ReplaceHTMLChars(
catch (Exception)


The GetDescription method opens the root URL of the RSS feeds, and searches the titles for the code of the airport it’s currently updating (e.g. LAX), navigating through the possible feeds using the information from our list of airports. The client_DownloadStringCompleted method then takes this information, locates the given airport in the XML list and updates its property value with the current status of the airport, and finds the airport’s corresponding image on the map and sets its property value to match. To call the service that is now contained in the GetDescription (string search) method, find the _geoservice_GeocodeCompleted method, and after the line:

airport.Location e.Result.Results = [ 0]. Locations [0]

…call the GetDescription method, passing the ID property of the airport variable as a parameter:

GetDescription (airport.ID)

The end result should look like this:

Figure 9. The finished application, locating U.S airports and reporting on their current status (click on the image for an enlarged view).


You can download the complete project from the top of this article to see the finished result. This little application only scratches the surface of Bing maps and the services it provides, and is similarly a very basic demonstration of Silverlight’s abilities. Nevertheless, you’ll hopefully agree that this was a very simple application to write, and that it was relatively easy to manipulate multiple data sources to get the desired results.

Djonatas Tenfen

Author profile:

A C# Developer focusing on ASP.NET and Silverlight, Djonatas Tenfen is a specialist consultant in application development with Silverlight and WCF Ria Serivices. He is also a community leader of Silverlight Brazil, a Webcaster for MSDN Brazil, an administrator of several MSDN webcast portals, and a Microsoft Certified Professional (.NET Framework 2.0). Djonatas blogs on Live Spaces, and you can follow him on twitter (@djonatastenfen).

Search for other articles by Djonatas Tenfen

Rate this article:   Avg rating: from a total of 30 votes.





Must read
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.

Subject: Nice Shot
Posted by: laerte (view profile)
Posted on: Friday, July 16, 2010 at 9:44 AM
Message: My good friend, It is a great pleasure to see you here at Simple-Talk. You are one of the biggest names in Silverlight and it certainly is the beginning of a great success. Congratulations

Subject: Very Good
Posted by: Sara Barbosa (not signed in)
Posted on: Friday, July 16, 2010 at 4:25 PM
Message: Congratulations!!! :D

Subject: Congratulations
Posted by: Fernanda Sallai (not signed in)
Posted on: Friday, July 16, 2010 at 8:57 PM
Message: Congratulations!!!!!

Subject: A map with green things on it?
Posted by: Anonymous (not signed in)
Posted on: Sunday, July 18, 2010 at 9:35 PM
Message: Does it really show anything useful?

Subject: RES: Does it really show anything useful?
Posted by: Djonatas (not signed in)
Posted on: Sunday, July 18, 2010 at 11:17 PM
Message: During normal operation of airports messages are similar, but if any problems with the information problem at the airport but the information is changed, and I show that we can cross multiple data sources and apply them on the BingMaps.

Subject: 10 points !!!
Posted by: (not signed in)
Posted on: Monday, July 19, 2010 at 12:06 AM
Message: Congratulations, marvellous. It's great for me, I'm newbie in Silverlight, this article is great reference for learn with real application. I hope more applications with source code like this, high level. Thanks !!!

Subject: RES: 10 points !!!
Posted by: djonatas (view profile)
Posted on: Monday, July 19, 2010 at 12:29 AM
Message: português para inglêsMostrar romanização
Happy to be participating and contributing to their learning

Subject: nonsense
Posted by: Anonymous (not signed in)
Posted on: Monday, July 19, 2010 at 2:29 AM
Message: Waste of time! For readers and for the writer

Subject: Great article
Posted by: Anonymous (not signed in)
Posted on: Monday, July 19, 2010 at 2:48 AM
Message: This is a really useful example of using Silverlight in a mashup. Thanks for that. It is great to have the source as a learning aid.

Subject: Wow Super
Posted by: Anonymous (not signed in)
Posted on: Monday, July 19, 2010 at 9:49 PM
Message: Thanks for sharing
I learned useful information from this article
Once again thank u

Subject: Excellent
Posted by: DrT (not signed in)
Posted on: Monday, July 26, 2010 at 4:16 AM
Message: Very nice article - shows a lot of concepts clearly. Thanks!

Subject: No Bing dlls downloaded with SDK
Posted by: Edward (view profile)
Posted on: Tuesday, July 27, 2010 at 1:36 PM
Message: I downloaded and installed Bing 2.0 SDK. All I get is a folder with some samples and a chm file. No dlls nothing in Program files at all. So right from the start am not able to even start application.

Subject: Edward
Posted by: djonatas (view profile)
Posted on: Monday, August 2, 2010 at 6:17 PM
Message: The Download of Dlls is possible in


Subject: rssfeeds lat/long information
Posted by: raghu.m26 (view profile)
Posted on: Monday, January 10, 2011 at 4:49 AM
Message: Hi Djonatas Tenfen,

Thanks for your post on Airport mushup's its really very helpful for me, as i have to do a similar kind of work.

could you please tell me how did you create Airport.xml file. (ID and Name).

i want to do the same for :
could you please help me

Thanks in Advance.


Top Rated

ASP.NET SignalR: Old-fashioned Polling, Just Done Better
 A website often needs to update a page as the underlying data changes. You can, of course, just poll... Read more...

Rethinking the Practicalities of Recursion
 We all love recursion right up to the point of actually using it in production code. Why? Recursion... Read more...

Acceptance Testing with FitNesse: Multiplicities and Comparisons
 FitNesse is one of the most popular tools for unit testing since it is designed with a Wiki-style... Read more...

Acceptance Testing with FitNesse: Documentation and Infrastructure
 FitNesse is a popular general-purpose wiki-based framework for writing acceptance tests for software... Read more...

Prototyping Desktop Deblector
 Deblector is an open-source debugging add-in for .NET Reflector; the Reflector team investigated... Read more...

Most Viewed

A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

Calling Cross Domain Web Services in AJAX
 The latest craze for mashups involves making cross-domain calls to Web Services from APIs made publicly... Read more...

10 Reasons Why Visual Basic is Better Than C#
 After having converted a whole lot of training materials based on VB.NET into C#, Andy ‘Wise Owl’ Brown... Read more...

Why Join

Over 400,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.