Geoffrey Emery
Tech Goodness

Free training on Visual Studio 2010 and C# 4.0

October 28, 2009 09:11 by Geoffrey Emery

Did you know that you can train yourself for what’s new in Visual Studio 2010 and C# 4.0 (also VB) ?

The Microsoft Visual Studio 2010 and .NET Framework 4 Training Kit - October Preview is available for more than a week now and it includes lots of slide decks, demos and labs covering the following topics:

  • Whats New In the .NET Framework 4
  • Whats New In Visual Studio 2010
    • Video: Downloading And Installing Visual Studio 2010 Beta 2
    • Demo: Hello Visual Studio 2010
  • Common Language Runtime
    • Demo: System.Threading.Barrier Demo
    • Demo: System.Threading.CountdownEvent
  • Managed Languages
    • What's New In C# 4 and Visual Basic 10
    • Video: Fixing PIA Pains with Type Equivalence
    • Demo: Managed Languages 10-in-1
    • Lab: Introduction To F#
    • Lab: Visual Studio 2010: Office Programmability
    • Lab: Visual Studio 2010: Test Driven Development
  • ASP.NET 4
    • Introduction to ASP.NET MVC
    • Whats New In ASP.NET AJAX 4
    • Whats New In ASP.NET Web Forms 4
    • Web Deployment with Visual Studio 2010
    • Video: Simplifying Data-Driven Web Applications
    • Demo: AdventureWorks using AJAX
    • Demo: ASP.NET AJAX 10-in-1
    • Lab: ASP.NET AJAX
    • Lab: Building an Web Application
    • Lab: Enhancing a Web Application
    • Lab: Introduction to ASP.NET Web Forms 4.0
    • Lab: Web Development in Visual Studio 2010
  • Windows
    • What's New in Windows Presentation Foundation 4
    • Lab: Building a Data-Driven Master/Detail Business Form in WPF using Visual Studio 2010
    • Lab: Taskbar - MFC
    • Lab: Gestures - MFC
    • Lab: Multitouch - MFC
    • Lab: Ribbon – MFC
  • Windows Workflow
    • Workflow 4: A First Look
    • Video: Workflow Web Services
    • Lab: Introduction to Workflow 4.0
    • Lab: WCF Service Discovery using .NET Framework 4.0
  • Windows Communication Foundation
    • Lab: WCF Service Discovery using .NET Framework 4.0
  • Silverlight
    • Introduction to .NET RIA Services
  • Data Access
    • Whats New In Entity Framework 4
    • Whats New In ADONET Data Services 1.5
    • Introduction to Project "Velocity"
    • Video: Server-Driven Paging with ADO.NET Data Services
    • Demo: Project Velocity
    • Lab: Introduction to ADO.NET Data Services
    • Lab: Introduction To Project "Velocity"
  • Parallel Computing
    • Parallel Computing for Managed Developers
    • Demo: ContosoAutomotive Demo
    • Demo: BabyNames
    • Demo: Parallel.For Loop
    • Demo: Parallel LINQ (PLINQ)
    • Demo: System.Threading.Tasks
    • Lab: Parallel Extensions: Building Multicore Applications with .NET
  • Extensibility
    • Introduction to the Managed Extensibility Framework
    • Video: MEF Preview 7
    • Demo: Demos for "Intro to Mef" Presentation
    • Lab: Introduction To Managed Extensibility Framework
  • Application Lifecycle Management

Download the Visual Studio 2010 and .NET Framework 4 Training Kit - October Preview

Channel 9 also hosting lots of VS 2010 & .NET 4.0 Training classes


Best Practices for Virtual Earth development (AJAX control)

May 7, 2009 22:04 by gemery

 

Great posts in the forum I thought i would share here

Best Practices for Virtual Earth development (AJAX control)

General

1. To ensure proper rendering of the map use the following meta-tag and DOCTYPE:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd ">

2. Always specify a position, width, and height style property for the map div.

3. If possible specify starting coordinate and zoom level in the VEMap.LoadMap method. This will reduce the number of unneeded tiles that are loaded.

4. If a lot of panning is expected then set the tileBuffer property of the VEMap.LoadMap method for better user experience.

5. Minify JavaScript files and CSS style sheets.

6. If making multiple Find calls in sequence use recursion: http://rbrundritt.spaces.live.com/blog/cns!E7DBA9A4BFD458C5!739.entry

7. Use VEMap.SetCenterAndZoom function instead of two separate function calls to VEMap.SetCenter and VEMap.SetZoom.

8. Use VEMap.Dispose map on page unload to release browser resources.

9. If loading multiple shape layers and allowing user to switch between layers then hide/show layers rather than deleting and reloading.

10. UseVEMap. onLoadMap property to process post map load functions: http://msdn.microsoft.com/en-us/library/bb412504.aspx

11. Hide birdseye pop-up for better user experience:

document.getElementById(‘MSVE_obliqueNotification’).style.display = “none”;

document.getElementById(‘MSVE_obliqueNotification’).style.visibility = “hidden”;

12. Create custom navigation dashboard rather than modifying the existing one. This will make it easier to migrate to newer versions of the map control.

13. If 3D is not required then disable hotkeys (the number 3), and hide the 3D button. This will ensure that the user will not accidentally navigate into 3D.

Rather than hide the 3D button (using CSS), you should set the showSwitch parameter of the LoadMap() method to false. (I'm sure this is what you meant, but just to clarify)

14. If expecting user to only search within one country then append the country’s name to the end of all addresses being used in find searches if the user has not already specified the country. This will prevent Virtual Earth from searching against the worldwide data and will increase the chances of relevant results being returned. The same applies for addresses being used for driving directions.

15. If user is required to scroll the web page to see the map, then consider disabling the mouse scroll wheel event on the map. This will keep the user from accidentally zooming the map.

16. Disable the VE disambiguation box that occurs for find searches and create your own. This will give you the developer greater control over its functionality.

17. Ensure to enable printing for maps that the users may print. http://msdn.microsoft.com/en-us/library/cc469977.aspx

18) Add the following to the <head> of your web page:

<meta http-equiv="Accept-Encoding" content="gzip, deflate" />

This will also help when you're serving vector data via AJAX - but don't forget to set your web server compression on.

Shapes only in 2D:

 

1. add pushpins to a div rather than a VEShapeLayer for performance increases: http://blogs.msdn.com/virtualearth/archive/2009/04/09/virtual-earth-api-release-information-april-2009.aspx

2. If you need a custom pop-up, overlay an absolutely positioned div over the map and move it around. Otherwise use the custom the VEMap.ClearInfoBoxStyles method and specify your own styles. http://msdn.microsoft.com/en-us/library/bb412441.aspx

3. Disable shape display threshold when working with only a few polygons/polygons so that there is no loss in shape precision: http://msdn.microsoft.com/en-us/library/bb964367.aspx

Shapes in 3D

1.              1. Always use the VECustomIconSpecification for custom pushpins.

VECustomIconSpecification

1.               1. Use an absolute path for icon images.

2.               2. If not using the TextContent property of the VECustomIconSpecification, add a space character instead of an empty string. This is a work around for a bug in VE.

Data

1. Ensure that client data is in the proper projection system, WGS84. NAD83 will also work (~1m offset from WGS84 in certain areas of the world).

Absolutely! It might be worth mentioning that if you do have data projected in NAD27, or the British National Grid, for example, then you can reproject it into WGS84 using freely-available FWTools (http://fwtools.maptools.org/)

2. Use AJAX to retrieve data rather than post backs. This will allow you to retrieve your data without having to reload the map. This is much faster.

3. When working with latitude and longitude coordinates only six decimal places are needed. Any more decimal places will not change the pixel position on the map. This will reduce the overall size of the data being retrieved.

4. If there are a lot of pushpins (20+) on the map then clustering should be used.

a. If there is 100 of less pushpins then use the VEClusterSpecification: http://msdn.microsoft.com/en-us/library/bb412546.aspx

b. If there are 100 – 1000 pushpins use custom client side clustering algorithm: http://msdn.microsoft.com/en-us/library/cc161072.aspx

c. If there are 1000+ pushpins use server side clustering  (many algorithms exist)

5. Watch for floating point issues when doing calculations with coordinates. http://en.wikipedia.org/wiki/Floating_point#Problems_with_floating-point

6. When there is a lot of data, only load data for the current map view. Update data as the user navigates the map.

7. If possible run ESRI shapefile polygons/polyline data through a reduction algorithm to reduce the number of coordinates used to represent the shapes. ESRI shapefiles typically are large and use multiple coordinates (20+) to represent a straight line when only two are needed.

I agree with the comment that shapefiles should be reduced, but we need to be careful about the concept of 'straight lines' and how many coordinates are needed... because I would argue that it is Virtual Earth that handles these incorrectly rather than shapefiles.
Consider an ESRI shapefile with a single 'straight' linestring drawn between two coordinates at (34, -118) and (52 ,0), representing a route between Los Angeles and London. These coordinates are measured in WGS84, which uses geographic coordinates on an ellipsoidal model of the Earth. The shortest 'straight' line route between these two points, when projected onto a Mercator map, is therefore:

8. Polygon and Polyline data can be encoded to reduce its size: http://www.soulsolutions.com.au/Articles/Encodingforperformance.aspx

9  "If plotting complex shapes that are relatively static, and which you don't need to be able to interact with, use a tile layer rather than a shape layer."
10  "To generate your own background tiles you can use MSR mapcruncher. If you want to replace the default VE tileset completely with your own tiles then set the LoadBaseTiles map option to false when calling the LoadMap method"

 

Most of this came from the most awsome

and some from the sql spatial guru himselft

Ricky Brundritt

http://rbrundritt.spaces.live.com/default.aspx?sa=324131751

aitchison

http://www.beginningspatial.com/

Great Job


Send Email From Asp.Net

April 28, 2009 08:39 by gemery

I just finished a client app with a web form to send email. Being that this used to be old hat i found that i had lost all my sample code for this. So here it is for reference.

The process of sending mail is the same for Windows apps and asp.net websites as the same .Net classes are used. The process can be slightly shortened by specifying default SMTP settings in the web.config or app.config file. Here, I’m showing the full version of the code and it does not rely on any configuration settings. The code also specifies unicode encoding for the subject and body.

using System.Net.Mail; 
using System.Net;
//Create the mail message 
MailMessage mail = new MailMessage(); 
mail.Subject = "Subject"; 
mail.Body = "Main body goes here";
//the displayed "from" email address 
mail.From = new System.Net.Mail.MailAddress(you@live.com);  
mail.IsBodyHtml = false; 
mail.BodyEncoding = System.Text.Encoding.Unicode; 
mail.SubjectEncoding = System.Text.Encoding.Unicode; 
//Add one or more addresses that will receive the mail 
mail.To.Add("me@live.com"); 
//create the credentials 
NetworkCredential cred = new NetworkCredential( 
"you@live.com", //from email address of the sending account 
"password"); //password of the sending account 
//create the smtp client...these settings are for gmail 
SmtpClient smtp = new SmtpClient("smtp.gmail.com"); 
smtp.UseDefaultCredentials = false; 
smtp.EnableSsl = true;
//credentials (username, pass of sending account) assigned here 
smtp.Credentials = cred;  
smtp.Port = 587; 
//let her rip 
smtp.Send(mail);

Tags: ,
Categories: Tutorials | Code
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

Enforcing a Common Spatial Reference ID in SQL Server

April 22, 2009 18:13 by gemery

 

This enables you to not let any other Spatial Reference ID inserted into a spatial column. This is inherently allowed but when you want to do operations on the column they must all be of the same spatial reference.

 

alter table customers 
add constraint [enforce_SRID_GeogaphyColumn]
check (location.STSrid = 4326)

 

 

create TABLE customers
(
  FirstName nvarchar(30),
  LatName nvarchar(30)
)
alter table customers 
add location geography
alter table customers 
add constraint [enforce_SRID_GeogaphyColumn]
check (location.STSrid = 4326)
drop table customers

Adding Spatial Data Type To Existing Table

April 22, 2009 18:05 by gemery

 

You just found out that sql server 2008 has spatial support and you want to add a spatail refrence to that the table? Here is how

 

create TABLE customers
(
  FirstName nvarchar(30),
  LatName nvarchar(30)
)
alter table customers 
add location geography

Virtual Earth Server Side Control – Changing the Map Properties on the Server

February 24, 2009 13:15 by gemery

If you a have landed on this page please go ahead and take a gander at the Getting Started Page

 http://blog.geoffreyemery.com/post/Virtual-Earth-Server-Side-Control-ndash3b-Getting-Started.aspx

Next we have the setting the properties tutorial to browse

Now lets jump into setting the map control using server side components as well

First lets take a look at the final product.

So we are getting a standarrd map. but we are adding a bunch of server side buttons to interact with map…Namely ZoomIn, ZoomOut, Change the map to Arial,and Road, and Arial With Labels.

So how are hooking into these controls?

On the server just as we normally wood. Lets take a look at the code behind.

  protected void Page_Load(object sender, EventArgs e)
    {
    }
    protected void ZoomIn_Click(object sender, EventArgs e)
    {
        Map1.ZoomIn();
    }
    protected void ZoomOut_Click(object sender, EventArgs e)
    {
        Map1.ZoomOut();
    }
    protected void Aerial_Click(object sender, EventArgs e)
    {
        Map1.MapStyle = MapStyle.Aerial;
        
    }
    protected void Road_Click(object sender, EventArgs e)
    {
        Map1.MapStyle = MapStyle.Road;
    }
    protected void Hybrid_Click(object sender, EventArgs e)
    {
        Map1.MapStyle = MapStyle.Shaded;
    }

we also need to add a reference to the VE Class that was added to our bin when we dragged the control onto the web page.

using Microsoft.Live.ServerControls.VE;

 

And you will see that every time we click the button that the page posts back to the server and modifies the map. This is incredibly inefficient but the purpose was to demonstrate how you can change the map from the server! Sweet Lets take a look at that final product one more time.

image_thumb1[4]


Virtual Earth Server Side Control – Setting Map Properties

February 24, 2009 02:20 by gemery

image_thumb2If you a have landed on this page please go ahead and take a gander at the Getting Started Page http://blog.geoffreyemery.com/post/Virtual-Earth-Server-Side-Control-ndash3b-Getting-Started.aspx

So now that you have the got the control installed on your computer and you have installed the ctp you can then go ahead and get started.

Starting It up so go ahead and drag over the server control over to the page

Drag and drop control onto your web page - You can drag and drop the control from toolbox onto your web page and set some properties and you are ready to go.

clip_image002

Now we are going to go ahead and set some properties.  First we should have a look at the parameters created when dragging the control from the Toolbox and dropping it on a Web page. The default values in the description are also those created when dragging the control from the Toolbox and dropping it on a Web page.

ID

Required. The unique identifier for the control on the Web page. The default value is Map1.

Height

Optional. The height of the control on the Web page. The default value is 400px.

Width

Optional. The width of the control on the Web page. The default value is 400px.

ZoomLevel

Optional. The zoom level of the map on the Web page. The default value is 4.

Altitude

Optional. The altitude, in meters.

Center-Latitude

Optional. The latitude, in degrees, of the center of the map. The allowed range is from -90 (south pole) to 90 (north pole). The default value is 40.

Center-Longitude

Optional. The longitude, in degrees, of the center of the map. The allowed range is from -180 to 180. The default value is -104.

ClearInfoBoxStyles

Optional. Whether to clear any style settings for the information boxes. If true, the styles are cleared. The default value is false.

ClientToken

Optional. The unique client token from the Virtual Earth Platform service. Used to enable paid features and also track usage the token is received server side from the Virtual Earth Platform Web service. The default value is empty (""). Client tokens are required to get traffic information.

DashBoard

Optional. Whether to display the dashboard. If true, the dashboard is shown. The default value is true.

DashBoardSize

Optional. The size of the dashboard, if displayed. The allowed values are Tiny, Small, and Normal. The default value is Normal.

DisambiguationDialog

Optional. Whether to show the default disambiguation dialog is displayed when multiple results are returned from a location query. If true, the disambiguation dialog is displayed. The default value is true.

EnableShapeDisplayThreshold

Optional. Whether shapes are drawn below a threshold zoom level. If true, shapes are drawn below the threshold level. The default value is false.

Of going this for real first lets start off with blank ajax web site…

<%@ Page Language="VB"  AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="script1" />
    <div>
    </div>
    </form>
</body>
</html>

 

Now we are going to add the mapping control. Simply drag it across.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>
<%@ Register Assembly="Microsoft.Live.ServerControls.VE" Namespace="Microsoft.Live.ServerControls.VE"
    TagPrefix="ve" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Setting Map Porperties with the Virtual Earth Server Side Control</title>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager runat="server" ID="SM1" />
    <div>
        <ve:Map ID="Map1" runat="server" Height="400px" Width="400px" ZoomLevel="4" />
    </div>
    </form>
</body>
</html>

 

You will notice that you have a user control registered at the top and that the ve map control, and also notice that there is now a new dll in the bin folder that is inserted from dragging on the control.

image_thumb

Now you are ready go press f5 and lets see what you get…

image_thumb21

A ma centered on the US.  Awesome So lets set some properties.

Since mix is right around the corner lets set the map on the The belagio hotel.

change the map style to aerial , turn on the minmap and make the default measurement into kilometers not to mention play with the zoom level a bit.

 

<ve:Map ID="Map1" runat="server" Center-Latitude="36.11285" 
        Center-Longitude="-115.174" Height="600px" MapStyle="Aerial" MiniMap="True" 
        MiniMapSize="Large" MiniMapXoffset="520" MiniMapYoffset="5" 
        ScaleBarDistanceUnit="Kilometers" Width="720px" ZoomLevel="18" />

 

Now lets take a look at what we get.

image_thumb4

And that's its now we have set up our first virtual earth server side control.


Virtual Earth Server Side Control – Getting Started

February 22, 2009 21:25 by gemery

Key Links

Feature Overview

· Visual Studio toolbox - Map control is available right in your toolbox of Visual Studio

clip_image001

· Drag and drop control onto your web page - You can drag and drop the control from toolbox onto your web page and set some properties and you are ready to go.

clip_image002 clip_image003

clip_image004

· Server side events - Server side events for panning/zooming, find/directions are available in addition to client side events for the map control.

clip_image005 clip_image006

· Display and control the map - You can control how map displays on your web page with standard functionality like MapMode (2D/3D), MapStyle(Road/Aerial), displaying dashboard and setting its size, setting the zoom levels, zooming in/out, panning etc.

· Adding shapes to the map - You can add shapes to map from ASP.NET Server Side using provided methods. You can query different shapes/layers in the Map and delete them as well.

· Using directions - You can get the directions between multiple points using methods GetDirections. You can specify different routing options like distance unit, color etc. Once the direction information is received, Map control raises event OnServerDirections where you can process/render the returned information in way that suites your scenario.

clip_image007

clip_image008

clip_image009

· Using local search and mapping results - Map control provides with find method where you can search for local businesses in a specified location.

clip_image010

clip_image011

· Working with bird's eyes - Map control has support for bird's eye view similar to JavaScript control.

· Getting Traffic information - You can get traffic information and display on your web page. For this, you need to have an account with Virtual Earth Platform. You first need to get a client token:

Important: To get a Developer Evaluation account for Virtual Earth go to this link here and request one, https://mappoint-css.live.com/mwssignup/

clip_image012

· You can then use this client token to display the traffic of the location you are interested in:

clip_image013

Development stage

The suite of tools is currently a community technology preview, which means they would love feedback, but strongly discourage any web site from going live using these controls.

Original Post By Mark Brown… Reposting here for SEO… Mark has left VE Team so please Contact Chris Pendleton over at VE Blog

All this and more to come in the following tutorials


Launching the Mobile Device Emulator In Visual Studio

February 22, 2009 20:25 by gemery
  1. On the desktop computer, click Start | All Programs | Microsoft Visual Studio 2xxx| Microsoft Visual Studio 2xxx
  2. In Visual Studio 2xxx, click Tools | Device Emulator Manager.
  3. In Device Emulator Manger, right-click the name of the emulator, and then select Cradle, as shown in Figure 1.

    Bb278114.2c7b04c7-6e0c-4674-9463-0b3d3c51b669(en-us,MSDN.10).gif

    Figure 1. Cradling a device in Device Emulator Manager

    Bb278114.note(en-us,MSDN.10).gifNote:

    You need to have ActiveSync 4.0 or later installed on your desktop computer to be able to cradle the device. (Device Emulator Manager and the Device Emulator can work with ActiveSync 3.8, but Visual Studio 2005 only supports ActiveSync 4.0 and later).

    After you cradle the emulator, ActiveSync automatically detects that a new device has been connected. The ActiveSync icon in your system tray will turn green.

  4. Click OK if ActiveSync informs you that you will be able to synchronize only files, folders, and other items that Microsoft Outlook® does not use.

    You can either create a Guest partnership or a Standard partnership with the Device Emulator.

  5. Click Cancel when ActiveSync attempts to synchronize the emulator with your desktop computer (to retrieve Tasks, Calendar, Email, and Contacts). By clicking Cancel, you automatically set up a Guest partnership.

  6. Click OK to the additional ActiveSync messages.


How to Use the the Cellular Emulator in the Windows Mobile 6 SDK

February 22, 2009 15:42 by gemery

One of the very cool tools available in the Windows Mobile 6 SDK is the Cellular Emulator. The Cellular Emulator allows you to use the Windows Mobile Emulator to emulate making and receiving phone calls, as well as sending and receiving of SMS messages. However, getting it to work with your emulator is not so straight-forward. Follow the steps outlined below:

1. Launch Cellular Emulator from Start -> Programs -> Windows Mobile 6 SDK -> Tools -> Cellular Emulator.

2. Observe the COM port number used by the Cellular Emulator. For my example, it is COM3. You may see something similar or different (like COM4).

3. Launch the Windows Mobile 6 Professional Emulator (make sure it is not the Classic emulator) from within Visual Studio 2005. You can do so from Tools -> Device Emulator Manager and right-click on Windows Mobile 6 Professional Emulator and select Connect.

4. In the Windows Mobile 6 Professional Emulator, select File -> Configure... and click the Peripherals tab.

5. Under Serial port 0: enter the COM port number used by the Cellular Emulator. For my example, I enter COM3. Note that you have to manually enter the COM port; it is not listed in the dropdown list.

6. Finally, reset the Windows Mobile 6 Professional Emulator by selecting File -> Reset -> Soft. This step is essential!

You should now be able to get the Cellular Emulator to "talk" to the Windows Mobile 6 Professional Emulator.

Some common problems

1. From experience, you are likely to encounter problems with the Cellular Emulator if you install the Windows Mobile 6 SDK on a notebook. You are likely to see an error that says "COM17 is used, please verify" (or something similar). There is no official way to resolve this, but it seems like some folks managed to solve this by first uninstalling the Windows Mobile 6 SDK, then disable the Bluetooth services, followed by installing the Windows Mobile 6 SDK again.

2. If you find that the Windows Mobile emulator is not receiving SMS messages/phone calls made from the Cellular Emulator, the first place to check is the COM port settings in the Emulator Properties page. I encountered instances of this problem when the emulator started to lose the COM port settings after a while of use.


Virtual Earth Web Service – Get your search on

January 23, 2009 08:28 by gemery

In this tutorial we are going to look at what you need to get search going using virtual earth web services. Search provides a robust way to find local businesses and attractions around a given location.

 

image

Note:

You must!  change the username in the web.config

    <add key="VEUsername" value="YourKey"/>
    <add key="VEPassword" value="YourPassword"/>

with your own information

image

1) Learn about Tokens

Okay, so, first things first, you need to authenticate - see my post Authentication and Tokens with Virtual Earth for authentication.

2) Create  AJAX Website in VS

Now that you are dialed in with your virtual earth tokens we are going to dive right into the web services. Lets go ahead and create a web site in VS. I am going to spice this up a bit and make it Ajax enabled. So go ahead and install AJAX or if you are using VS2008 sp 1 you should be already cool. Through in a script manager down and a update panel, and a update progress manager down on the page. This is the web form should look like in between the body tags should look this now.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="5">
           <ProgressTemplate>
              
           </ProgressTemplate>
       </asp:UpdateProgress>
       <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
     
           </ContentTemplate>
       
       </asp:UpdatePanel>

 

3) Fill in the UI

The full default.aspx page

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>VE Web Services Search Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        Virtual Earth Web Services Search Sample
    </div>
    <br />
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
         <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="20">
            <ProgressTemplate>
                <img alt="updatepannel" src="Images/Update.gif" />
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <table>
                    <tr>
                        <td>What:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_What" Width="250" /></td>
                    </tr>
                    <tr>
                        <td>Where:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_Where" Width="250" /></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td align="right">
                            <asp:Button runat="server" Text="Search and show map" ID="Button_SearchWithMap" 
                                onclick="Button_SearchWithMap_Click" />
                        </td>
                    </tr>
                </table>
 
                <table>
                    <tr>
                        <td>
                            <div runat="server" id="Div_SearchResults" style="width:300px; height:400px; overflow:auto"></div>
                        </td>
                        <td>
                            <asp:Image runat="server" ID="Image_Map" Visible="false" Height="400" Width="400" />
                        </td>
                    </tr>
                </table>
            </ContentTemplate>
        
        </asp:UpdatePanel>
    
    </div>
    </form>
</body>
</html>

4) Add the token to the web.config

<appSettings>
<!--
  This username and password is supplied for demo purposes only.  Please do not use this account for 
  anything other than this demo.  This account is monitored very closely and will be deactivated if used improperly
  To get your own Virtual Earth account, go to https://mappoint-css.live.com/MwsSignup/.
-->
<add key="VEUsername" value="YourToken"/>
<add key="VEPassword" value="YourPassword"/>
 
appSettings>

5) Add the Utility Class

You can do this as you like. I like to keep it separate. This takes the user key and password out of the web.config and news up a new VECredential for you

using System.Net;
using VEAuthenticationService;
using System.Text.RegularExpressions;
using System.Configuration;
    public static class Utils
    {
        private static string GetVEUsername() { return ConfigurationManager.AppSettings["VEUsername"].ToString(); }
        private static string GetVEPassword() { return ConfigurationManager.AppSettings["VEPassword"].ToString(); }
 
        public static string StripHTMLTags(string HtmlToStrip)
        {
            return Regex.Replace(HtmlToStrip, @"<(.|\n)*?>", string.Empty);
        }
 
        /// <summary>Returns a token from the Virtual Earth web service</summary>
        public static string Token(string ClientIP)
        {
            // This token will expire so that should be handled appropriately
            
                // Create a CommonService so we can make the request
                CommonService commonService = new CommonService
                {
                    // Supply your Virtual Earth credentials
                    // to get a Virtual Earth developer account, go to https://mappoint-css.live.com/MwsSignup/
                    Credentials = new NetworkCredential(Utils.GetVEUsername(), Utils.GetVEPassword())
                };
 
                // Create a token specification
                TokenSpecification tokenSpecification = new TokenSpecification
                {
                    // Token will expire in 60 minutes, max is 480 minutes
                    TokenValidityDurationMinutes = 60,
                    // Supply the client's IP address
                    ClientIPAddress = ClientIP
                };
                return commonService.GetClientToken(tokenSpecification);
          }
    }
 
 
 
 
 
 
 
 

6) Add the Update Image of your choice to to images folder for the update panel progress bar. –> this might make more sense after you download the project

7) add  your web service reference

Add a web service by right clicking on the project

image

Geocode Service

http://staging.dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc?wsdl

Imagery Service

http://staging.dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc?wsdl

Search Service

http://staging.dev.virtualearth.net/webservices/v1/searchservice/searchservice.svc?wsdl

 

8) Add the Guts

Now we add the GUTS to the code behind of the default.aspx page

First I am going to load the page up with some default values for testing purposes

Now for the fun stuff Getting the map from Microsoft

protected void Page_Load(object sender, EventArgs e)
 {
     if (Page.IsPostBack == false)
     {
         this.TextBox_What.Text = "Coffee Shops";
         this.TextBox_Where.Text = "Fullerton California";
     }
 }

 

protected void Page_Load(object sender, EventArgs e)
  {
      if (Page.IsPostBack == false)
      {
          this.TextBox_From.Text = "State College Blvd , Fullerton, CA 92831";
          this.TextBox_To.Text = "Golden Gate Bridge";  //Safeco Field
      }
  }

 

And finally add a handler for the button click there are a ton of comments in here so ill those be your guide feel to ping me with more questions plus down load the code and run it is the best way to go.

 

Start our search request

/// <summary>Executes a search with the what and where supplied in the UI</summary>
    /// <returns>SearchResponse for the executed search</returns>
    protected SearchResponse ExecuteSearch()
    {
        // Create a SearchRequest with a StructuredQuery
        SearchRequest searchRequest = new SearchRequest();
        searchRequest.Credentials = new VESearchService.Credentials();
        searchRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
        //Create a structured Search Query object
        VESearchService.StructuredSearchQuery structuredQuery = new StructuredSearchQuery();
        structuredQuery.Keyword = this.TextBox_What.Text.Trim();
        structuredQuery.Location = this.TextBox_Where.Text.Trim();
 
        searchRequest.StructuredQuery = structuredQuery;
 
        // Execute the search
        SearchServiceClient searchServiceClient = new SearchServiceClient();
        SearchResponse searchResponse = searchServiceClient.Search(searchRequest);
 
        return searchResponse;
    }

Now add the search results to a map!

/// <summary>Executes a search and creates a map that displays the search results.</summary>
  /// <param name="sender">The sender</param>
  /// <param name="e">Event arguments</param>
  protected void Button_SearchWithMap_Click(object sender, EventArgs e)
  {
      // Clear our results output
      this.Div_SearchResults.InnerHtml = "";
 
      // Execute a search
      SearchResponse searchResponse = this.ExecuteSearch();
      bool foundSearchResult = false;
 
      // Create a map, specify search results with the map request so pushpins will be rendered on the map
      if (searchResponse != null)
      {
          // Create a new MapUriRequest
          VEImageryService.MapUriRequest mapUriRequest = new MapUriRequest();
 
          // Create a new Credential object and provide the token
          mapUriRequest.Credentials = new VEImageryService.Credentials();
          mapUriRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
          //Set the size of the map requested to the size of the image control
          mapUriRequest.Options = new MapUriOptions
          {
              ImageSize = new VEImageryService.SizeOfint
              {
                  Height = Convert.ToInt32(this.Image_Map.Height.Value),
                  Width = Convert.ToInt32(this.Image_Map.Width.Value)
              }
          };
 
          // Create a new pushpin list
          List<VEImageryService.Pushpin> pushpinList = new List<Pushpin>();
 
          // Add each of the search results to the pushpin list
          foreach (SearchResultSet searchResultSet in searchResponse.ResultSets)
          {
              int businessCounter = 0;
              foreach (BusinessSearchResult busniessSearchResult in searchResultSet.Results)
              {
                  foundSearchResult = true;
 
                  // Write the search result data to the info box
                  this.WriteInfo(++businessCounter + ") <b>" + busniessSearchResult.Name + "</b>");
                  this.WriteInfo("&nbsp;&nbsp;&nbsp;&nbsp;" + busniessSearchResult.Address.FormattedAddress);
                  string website = "";
                  if (busniessSearchResult.Website != null)
                      website = "<a href='" + busniessSearchResult.Website.ToString() + "'>Website</a>";
                  this.WriteInfo("&nbsp;&nbsp;&nbsp;&nbsp;" + busniessSearchResult.PhoneNumber + "&nbsp;&nbsp;&nbsp;&nbsp;" + website);
                  this.WriteInfo("");
 
                  // Build out the pushpin and add it to the list
                  Pushpin pushpin = new Pushpin();
                  // push pin labels only support 2 characters
                  pushpin.Label = businessCounter.ToString(); // += "asdf";
 
                  // Just get the first location returned
                  if (busniessSearchResult.LocationData.Locations.Length > 0)
                  {
                      //this.WriteInfo("Location: " + busniessSearchResult.LocationData.Locations[0].Latitude + "," + busniessSearchResult.LocationData.Locations[0].Longitude);
                      pushpin.Location = new VEImageryService.Location();
                      pushpin.Location.Latitude = busniessSearchResult.LocationData.Locations[0].Latitude;
                      pushpin.Location.Longitude = busniessSearchResult.LocationData.Locations[0].Longitude;
                  }
 
                  pushpinList.Add(pushpin);
              }
          }
 
          // Add the pushpin list (as an array) to the MapUriRequest
          mapUriRequest.Pushpins = pushpinList.ToArray();
          ImageryServiceClient imageryServiceClient = new ImageryServiceClient();
 
          // Get the map and render it on the UI
          MapUriResponse mapUriResponse = imageryServiceClient.GetMapUri(mapUriRequest);
          this.Image_Map.ImageUrl = mapUriResponse.Uri;
          this.Image_Map.Visible = true;
      }
 
      if (foundSearchResult == false)
          this.WriteInfo("No search results for query");
  }

One Little helper function

/// <summary>Writes information to the UI</summary>
 /// <param name="html">HTML to write to the UI</param>
 protected void WriteInfo(string html)
 {
     this.Div_SearchResults.InnerHtml += html + "<br/>\n";
 }

 

Bam there you have Search with map imagery of where everything is.

There is a ton more information that you can pull out of the objet I kept to just a few things for simplicity.

Download the code here.

image

One Last look at the finished Product

image

 

 

 

 

 

 

 

 


Virtual Earth Web Services – Create A Map Image from a Latitude Longitude

January 23, 2009 07:37 by gemery

In this tutorial we are going to look at what you need to get a map from a  Lat Long(GeoCode)

First a picture of what the final project will look like.

image

Note:

You must!  change the username in the web.config

    <add key="VEUsername" value="YourKey"/>
    <add key="VEPassword" value="YourPassword"/>

with your own information

image

1) Learn about Tokens

Okay, so, first things first, you need to authenticate - see my post Authentication and Tokens with Virtual Earth for authentication.

2) Create  AJAX Website in VS

Now that you are dialed in with your virtual earth tokens we are going to dive right into the web services. Lets go ahead and create a web site in VS. I am going to spice this up a bit and make it Ajax enabled. So go ahead and install AJAX or if you are using VS2008 sp 1 you should be already cool. Through in a script manager down and a update panel, and a update progress manager down on the page. This is the web form should look like in between the body tags should look this now.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="5">
           <ProgressTemplate>
              
           </ProgressTemplate>
       </asp:UpdateProgress>
       <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
     
           </ContentTemplate>
       
       </asp:UpdatePanel>

 

3) Fill in the UI

The full default.aspx page

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Virtual Earth Web Services Imagery Map Creation Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        VE Web Services Imagery Map Creation Sample
    </div>
    <br />
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="20">
            <ProgressTemplate>
                <img alt="updatepannel" src="Images/Update.gif" />
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                Latitude: <asp:TextBox runat="server" ID="TextBox_Latitude" Width="125" />
                Longitude: <asp:TextBox runat="server" ID="TextBox_Longitude" Width="125" />
                Zoom Level: <asp:DropDownList runat="server" ID="DropDownList_ZoomLevel" 
                    onselectedindexchanged="DropDownList_ZoomLevel_SelectedIndexChanged" AutoPostBack="true" />
                <br />
 
                <table>
                    <tr>
                        <td>&nbsp;</td>
                        <td>
                            <asp:Image ID="Image_Map" runat="server" Height="432px" Width="585px" />
                            <br />
                        </td>
                        <td align="center">&nbsp;</td>
                    </tr>
                </table>
                
                <br />
                <div runat="server" id="Div_Info" />
                
            </ContentTemplate>
        
        </asp:UpdatePanel>
    
    </div>
    </form>
</body>
</html>

4) Add the token to the web.config

<appSettings>
<!--
  This username and password is supplied for demo purposes only.  Please do not use this account for 
  anything other than this demo.  This account is monitored very closely and will be deactivated if used improperly
  To get your own Virtual Earth account, go to https://mappoint-css.live.com/MwsSignup/.
-->
<add key="VEUsername" value="YourToken"/>
<add key="VEPassword" value="YourPassword"/>
 
appSettings>

5) Add the Utility Class

You can do this as you like. I like to keep it separate. This takes the userkey and passowrd out of the webconfig and news up a new VECredential for you

using System.Net;
using VEAuthenticationService;
using System.Text.RegularExpressions;
using System.Configuration;
    public static class Utils
    {
        private static string GetVEUsername() { return ConfigurationManager.AppSettings["VEUsername"].ToString(); }
        private static string GetVEPassword() { return ConfigurationManager.AppSettings["VEPassword"].ToString(); }
 
        public static string StripHTMLTags(string HtmlToStrip)
        {
            return Regex.Replace(HtmlToStrip, @"<(.|\n)*?>", string.Empty);
        }
 
        /// <summary>Returns a token from the Virtual Earth web service</summary>
        public static string Token(string ClientIP)
        {
            // This token will expire so that should be handled appropriately
            
                // Create a CommonService so we can make the request
                CommonService commonService = new CommonService
                {
                    // Supply your Virtual Earth credentials
                    // to get a Virtual Earth developer account, go to https://mappoint-css.live.com/MwsSignup/
                    Credentials = new NetworkCredential(Utils.GetVEUsername(), Utils.GetVEPassword())
                };
 
                // Create a token specification
                TokenSpecification tokenSpecification = new TokenSpecification
                {
                    // Token will expire in 60 minutes, max is 480 minutes
                    TokenValidityDurationMinutes = 60,
                    // Supply the client's IP address
                    ClientIPAddress = ClientIP
                };
                return commonService.GetClientToken(tokenSpecification);
          }
    }
 
 
 
 
 
 
 
 

6) Add the Update Image of your choice to to images folder for the update panel progress bar. –> this might make more sense after you download the project

7) add  your web service reference

Add a web service by right clicking on the project

image

Imagery Service

http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc?wsdl

8) Add the Guts

Now we add the GUTS to the code behind of the default.aspx page

First I am going to load the page up with some default values for testing purposes

protected void Page_Load(object sender, EventArgs e)
    {
        if (Page.IsPostBack == false)
        {
            // Load some default data into the UI
 
            //Hotel Bonaventure, ( 34.052563, -118.256012 )
            //this.TextBox_Latitude.Text = "34.052563";
            //this.TextBox_Longitude.Text = "-118.256012";
 
            //Los Angeles Convention Center, ( 34.0404, -118.2688 )
            this.TextBox_Latitude.Text = "34.0404";
            this.TextBox_Longitude.Text = "-118.2688";
             
 
            //One Microsoft Way
            //this.TextBox_Latitude.Text = "47.64";
            //this.TextBox_Longitude.Text = "-122.13";
 
            for (int i = 1; i <= 20; i++)
                this.DropDownList_ZoomLevel.Items.Add(i.ToString());
            this.DropDownList_ZoomLevel.SelectedIndex = 18;     // Default the zoom level to 19
 
            // Load a default map
            this.RenderMap(Convert.ToDouble(this.TextBox_Latitude.Text),
                Convert.ToDouble(this.TextBox_Longitude.Text),
                Convert.ToInt32(this.DropDownList_ZoomLevel.SelectedValue));
        }
    }

Now for the fun stuff Getting the map from Microsoft

/// <summary>Renders and places a map image on the page</summary>
    /// <param name="centerLatitude">Latitude that the map should be centered on</param>
    /// <param name="centerLongitude">Longitude that the map should be centered on</param>
    /// <param name="zoomLevel">Zoom level of the map image</param>
    private void RenderMap(double centerLatitude, double centerLongitude, int zoomLevel)
    {
        Image mapImage = (Image)this.FindControl("Image_Map");
 
        // Create a new MapUriRequest
        VEImageryService.MapUriRequest mapUriRequest = new MapUriRequest();
         
        // Create a new Credential object and provide the token
        mapUriRequest.Credentials = new VEImageryService.Credentials();
        mapUriRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
        //Set the Center point for the imagery request
        mapUriRequest.Center = new VEImageryService.Location
        {
            Altitude = 0,
            Latitude = centerLatitude,
            Longitude = centerLongitude
        };
 
        // Set the size and ZoomLevel we want on the returned map
        mapUriRequest.Options = new MapUriOptions
        {
            // Specify the map size, we get this from the size of the image on the web page
            ImageSize = new VEImageryService.SizeOfint
            {
                Height = (int)mapImage.Height.Value,
                Width = (int)mapImage.Width.Value
            },
            // Set the ZoomLevel for the returned map
            ZoomLevel = (int)zoomLevel,
 
            //Set the Map Style (only road and aerial types are available)
            Style = MapStyle.AerialWithLabels
        };
 
        // Create a new ImageryServiceClient to make the service request
        ImageryServiceClient imageryServiceClient = new ImageryServiceClient();
 
        // Execute GetMapUri
        MapUriResponse mapUriResponse = imageryServiceClient.GetMapUri(mapUriRequest);
 
        // Display the map on the web page.
        mapImage.ImageUrl = mapUriResponse.Uri;
 
        // Write out the uri to the page
        this.WriteInfo("<b>Map uri: </b>" + mapUriResponse.Uri);
    }

And finally add a handler for when people change the zoom level and a small helper function

/// <summary>Event handler for the Zoom level drop down list, re-renders the map at the specified zoom level</summary>
   /// <param name="sender">The sender</param>
   /// <param name="e">Event arguments</param>
   protected void DropDownList_ZoomLevel_SelectedIndexChanged(object sender, EventArgs e)
   {
       this.RenderMap(Convert.ToDouble(this.TextBox_Latitude.Text),
           Convert.ToDouble(this.TextBox_Longitude.Text),
           Convert.ToInt32(this.DropDownList_ZoomLevel.SelectedValue));
   }
 
   /// <summary>Writes information to the UI</summary>
   /// <param name="html">HTML to write to the UI</param>
   protected void WriteInfo(string html)
   {
       this.Div_Info.InnerHtml += html + "<br/>\n";
   }

and Bam there you have a map coming at you from a longitude latitude. you need to do this from a address look at this example.

http://blog.geoffreyemery.com/post/Virtual-Earth-Web-Services----GeoCoding-and-Reverse-GeoCoding.aspx

After you geocode it you can then send in another request to get a map.

Download the code here.

image

  

Have fun!


Virtual Earth Web Service – Get Routing information

January 22, 2009 08:01 by gemery

In this tutorial we are going to look at what you need to get Routing information from a start and end point and then display them.

 

image

Note:

You must!  change the username in the web.config

    <add key="VEUsername" value="YourKey"/>
    <add key="VEPassword" value="YourPassword"/>

with your own information

image

1) Learn about Tokens

Okay, so, first things first, you need to authenticate - see my post Authentication and Tokens with Virtual Earth for authentication.

 

2) Create  AJAX Website in VS

Now that you are dialed in with your virtual earth tokens we are going to dive right into the web services. Lets go ahead and create a web site in VS. I am going to spice this up a bit and make it Ajax enabled. So go ahead and install AJAX or if you are using VS2008 sp 1 you should be already cool. Through in a script manager down and a update panel, and a update progress manager down on the page. This is the web form should look like in between the body tags should look this now.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="5">
           <ProgressTemplate>
              
           </ProgressTemplate>
       </asp:UpdateProgress>
       <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
     
           </ContentTemplate>
       
       </asp:UpdatePanel>

 

3) Fill in the UI

The full default.aspx page

 

<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Vritual Earth Web Services Route Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        Vritual Earth Web Services Route Sample
    </div>
    <br />
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="20">
            <ProgressTemplate>
                <img alt="updatepannel" src="Images/Update.gif" />
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <table>
                    <tr>
                        <td>From Address:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_From" Width="250" /></td>
                    </tr>
                    <tr>
                        <td>To Address:</td>
                        <td><asp:TextBox runat="server" ID="TextBox_To" Width="250" /></td>
                    </tr>
                    <tr>
                        <td></td>
                        <td align="right">
                            <asp:Button runat="server" Text="Get Directions" ID="Button_GetDirections" onclick="Button_GetDirections_Click" />
                        </td>
                    </tr>
                </table>
                <br />
 
                <div runat="server" id="Div_Directions" />
                <br />
                <asp:Image runat="server" ID="Image_Map" Visible="false" />
            </ContentTemplate>
        
        </asp:UpdatePanel>
    
    </div>
    </form>
</body>
</html>

4) Add the token to the web.config

<appSettings>
<!--
  This username and password is supplied for demo purposes only.  Please do not use this account for 
  anything other than this demo.  This account is monitored very closely and will be deactivated if used improperly
  To get your own Virtual Earth account, go to https://mappoint-css.live.com/MwsSignup/.
-->
<add key="VEUsername" value="YourToken"/>
<add key="VEPassword" value="YourPassword"/>
 
appSettings>

5) Add the Utility Class

You can do this as you like. I like to keep it separate. This takes the user key and password out of the web.config and news up a new VECredential for you

using System.Net;
using VEAuthenticationService;
using System.Text.RegularExpressions;
using System.Configuration;
    public static class Utils
    {
        private static string GetVEUsername() { return ConfigurationManager.AppSettings["VEUsername"].ToString(); }
        private static string GetVEPassword() { return ConfigurationManager.AppSettings["VEPassword"].ToString(); }
 
        public static string StripHTMLTags(string HtmlToStrip)
        {
            return Regex.Replace(HtmlToStrip, @"<(.|\n)*?>", string.Empty);
        }
 
        /// <summary>Returns a token from the Virtual Earth web service</summary>
        public static string Token(string ClientIP)
        {
            // This token will expire so that should be handled appropriately
            
                // Create a CommonService so we can make the request
                CommonService commonService = new CommonService
                {
                    // Supply your Virtual Earth credentials
                    // to get a Virtual Earth developer account, go to https://mappoint-css.live.com/MwsSignup/
                    Credentials = new NetworkCredential(Utils.GetVEUsername(), Utils.GetVEPassword())
                };
 
                // Create a token specification
                TokenSpecification tokenSpecification = new TokenSpecification
                {
                    // Token will expire in 60 minutes, max is 480 minutes
                    TokenValidityDurationMinutes = 60,
                    // Supply the client's IP address
                    ClientIPAddress = ClientIP
                };
                return commonService.GetClientToken(tokenSpecification);
          }
    }
 
 
 
 
 
 
 
 

6) Add the Update Image of your choice to to images folder for the update panel progress bar. –> this might make more sense after you download the project

7) add  your web service reference

Add a web service by right clicking on the project

image

image

Geocode Service

http://staging.dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc?wsdl

Imagery Service

http://staging.dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc?wsdl

 

8) Add the Guts

Now we add the GUTS to the code behind of the default.aspx page

First I am going to load the page up with some default values for testing purposes

Now for the fun stuff Getting the map from Microsoft

protected void Page_Load(object sender, EventArgs e)
  {
      if (Page.IsPostBack == false)
      {
          this.TextBox_From.Text = "State College Blvd , Fullerton, CA 92831";
          this.TextBox_To.Text = "Golden Gate Bridge";  //Safeco Field
      }
  }

 

And finally add a handler for the button click there are a ton of commonts in here so ill those be your guide feel to ping me iwth more questions plus down load the code and run it is the best way to go.

/// <summary>Displays directions from a point to another point based on the address supplied in the UI</summary>
    /// <param name="sender">The sender</param>
    /// <param name="e">Event arguments</param>
    protected void Button_GetDirections_Click(object sender, EventArgs e)
    {
        // Create a new RouteRequest and set our credentials
        RouteRequest routeRequest = new RouteRequest();
        routeRequest.Credentials = new VERouteService.Credentials();
        routeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
 
        // Create a new list of Waypoints and add start and end locations to the list
        List<Waypoint> wayPointList = new List<Waypoint>();
        wayPointList.Add(this.GetWayPointFromAddress("Start", this.TextBox_From.Text.Trim()));
        wayPointList.Add(this.GetWayPointFromAddress("End", this.TextBox_To.Text.Trim()));
 
        // Add the list of waypoints to the route request
        routeRequest.Waypoints = wayPointList.ToArray();
 
        // New up a RouteServiceClient
        RouteServiceClient routeServiceClient = new RouteServiceClient();
 
 
        //and calculate the route
        RouteResponse routeResponse = routeServiceClient.CalculateRoute(routeRequest);
 
        // Write the route directions back to the UI
        int legCounter = 0;
        foreach (RouteLeg routeLeg in routeResponse.Result.Legs)
        {
            foreach (ItineraryItem itineraryItem in routeLeg.Itinerary)
                this.WriteInfo((++legCounter) + ") " + itineraryItem.Text);
        }
    }
 
    /// <summary>Returns a waypoint given from the specified address</summary>
    /// <param name="description">Waypoint description</param>
    /// <param name="address">Address to geocode against</param>
    protected Waypoint GetWayPointFromAddress(string description, string address)
    {
        // Create a waypoint, new up the a location object and set the description
        Waypoint wayPoint = new Waypoint
        {
            Description = description,
            Location = new VERouteService.Location()
        };
 
        // New up a geocode request and supply the credentials 
        GeocodeRequest geocodeRequest = new GeocodeRequest();
        geocodeRequest.Credentials = new VEGeocodeService.Credentials();
        geocodeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
        //pass the address of the location
        geocodeRequest.Query = address;
 
 
        // Create a GeocodeService client and execute the Geocode method
        GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient();
        GeocodeResponse geocodeResponse = geocodeServiceClient.Geocode(geocodeRequest);
 
        // If we have a geocode result, set the first result to our waypoint location
        if (geocodeResponse.Results.Length > 0)
        {
            if (geocodeResponse.Results[0].Locations.Length > 0)
            {
                wayPoint.Location.Latitude = geocodeResponse.Results[0].Locations[0].Latitude;
                wayPoint.Location.Longitude = geocodeResponse.Results[0].Locations[0].Longitude;
            }
        }
 
        return wayPoint;
    }

One Little helper function

/// <summary>Writes information to the UI</summary>
   /// <param name="html">HTML to write to the UI</param>
   protected void WriteInfo(string html)
   {
       this.Div_Directions.InnerHtml += html + "<br/>\n";
   }

Bam there you have a routing simply from two peoples address… Sweet.

There is a ton more information that you can pull out of the objet I kept to just a few things for simplicity.

Download the code here.

image

One Last look at the finished Product

image

 

 

 

 

 

 

 


Virtual Earth Web Service - Get Server Tile Information

January 21, 2009 23:35 by gemery

In this tutorial we are going to look at what you need to get Tile information from a lat Lat Long(GeoCode) 

First a picture of what the final project will look like.

image

Note:

You must!  change the username in the web.config

    <add key="VEUsername" value="YourKey"/>
    <add key="VEPassword" value="YourPassword"/>

with your own information

image

1) Learn about Tokens

Okay, so, first things first, you need to authenticate - see my post Authentication and Tokens with Virtual Earth for authentication.

 

2) Create  AJAX Website in VS

Now that you are dialed in with your virtual earth tokens we are going to dive right into the web services. Lets go ahead and create a web site in VS. I am going to spice this up a bit and make it Ajax enabled. So go ahead and install AJAX or if you are using VS2008 sp 1 you should be already cool. Through in a script manager down and a update panel, and a update progress manager down on the page. This is the web form should look like in between the body tags should look this now.

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="5">
           <ProgressTemplate>
              
           </ProgressTemplate>
       </asp:UpdateProgress>
       <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
     
           </ContentTemplate>
       
       </asp:UpdatePanel>

 

3) Fill in the UI

The full default.aspx page

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
<html xmlns="http://www.w3.org/1999/xhtml">
 <head id="Head1" runat="server">
    <title>VE Web Services Imagery Tile Sample</title>
</head>
<body style="font-family:Arial; font-size:small">
    <form id="form1" runat="server">
    <div style="font-weight:bold">
        VE Web Services Imagery Tile Sample
    </div>
    <br />
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="20">
            <ProgressTemplate>
                <img alt="updatepannel" src="Images/Update.gif" />
            </ProgressTemplate>
        </asp:UpdateProgress>
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                Latitude: <asp:TextBox runat="server" ID="TextBox_Latitude" Width="125" />
                Longitude: <asp:TextBox runat="server" ID="TextBox_Longitude" Width="125" />
                Zoom Level: <asp:DropDownList runat="server" ID="DropDownList_ZoomLevel" />
                <br />
                <asp:Button runat="server" Text="Load Tile" ID="Button_LoadTile" 
                    onclick="Button_LoadTile_Click" />
                <br /><br />
                <div runat="server" id="Div_Info" />
                <asp:PlaceHolder runat="server" ID="PlaceHolder_MapImages" />
            </ContentTemplate>
        </asp:UpdatePanel>
    
    </div>
    </form>
</body>
</html>

4) Add the token to the web.config

<appSettings>
<!--
  This username and password is supplied for demo purposes only.  Please do not use this account for 
  anything other than this demo.  This account is monitored very closely and will be deactivated if used improperly
  To get your own Virtual Earth account, go to https://mappoint-css.live.com/MwsSignup/.
-->
<add key="VEUsername" value="YourToken"/>
<add key="VEPassword" value="YourPassword"/>
 
appSettings>

5) Add the Utility Class

You can do this as you like. I like to keep it separate. This takes the user key and password out of the web.config and news up a new VECredential for you

using System.Net;
using VEAuthenticationService;
using System.Text.RegularExpressions;
using System.Configuration;
    public static class Utils
    {
        private static string GetVEUsername() { return ConfigurationManager.AppSettings["VEUsername"].ToString(); }
        private static string GetVEPassword() { return ConfigurationManager.AppSettings["VEPassword"].ToString(); }
 
        public static string StripHTMLTags(string HtmlToStrip)
        {
            return Regex.Replace(HtmlToStrip, @"<(.|\n)*?>", string.Empty);
        }
 
        /// <summary>Returns a token from the Virtual Earth web service</summary>
        public static string Token(string ClientIP)
        {
            // This token will expire so that should be handled appropriately
            
                // Create a CommonService so we can make the request
                CommonService commonService = new CommonService
                {
                    // Supply your Virtual Earth credentials
                    // to get a Virtual Earth developer account, go to https://mappoint-css.live.com/MwsSignup/
                    Credentials = new NetworkCredential(Utils.GetVEUsername(), Utils.GetVEPassword())
                };
 
                // Create a token specification
                TokenSpecification tokenSpecification = new TokenSpecification
                {
                    // Token will expire in 60 minutes, max is 480 minutes
                    TokenValidityDurationMinutes = 60,
                    // Supply the client's IP address
                    ClientIPAddress = ClientIP
                };
                return commonService.GetClientToken(tokenSpecification);
          }
    }
 
 
 
 
 
 
 
 

6) Add the Update Image of your choice to to images folder for the update panel progress bar. –> this might make more sense after you download the project

7) add  your web service reference

Add a web service by right clicking on the project

image 

Imagery Service

http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc?wsdl

8) Add the Guts

Now we add the GUTS to the code behind of the default.aspx page

First I am going to load the page up with some default values for testing purposes

Now for the fun stuff Getting the map from Microsoft

/// <summary>Loads a tile map tile that contains the specified latitude and longitude</summary>
   /// <param name="sender">The sender</param>
   /// <param name="e">Event arugments</param>
   protected void Button_LoadTile_Click(object sender, EventArgs e)
   {
       // Clear our outputs before we start.
       this.PlaceHolder_MapImages.Controls.Clear();
       this.Div_Info.InnerHtml = "";
 
       // Create a ImageryMetadataOptions object
       ImageryMetadataOptions imageryMetadataOptions = new ImageryMetadataOptions
       {
           // Specify the location, this will not necessarly be the middle of the tile
           Location = new Location
           {
               Altitude = 0,
               Latitude = Convert.ToDouble(this.TextBox_Latitude.Text),
               Longitude = Convert.ToDouble(this.TextBox_Longitude.Text)
           },
           ReturnImageryProviders = true,
           ZoomLevel = Convert.ToInt32(this.DropDownList_ZoomLevel.SelectedItem.ToString()),
       };
 
       // Create the metadata request, set the credentials, options and a map style
       ImageryMetadataRequest imageryMetadataRequest = new ImageryMetadataRequest
       {
           //add the metadata options object from above
           Options = imageryMetadataOptions,
           Style = MapStyle.AerialWithLabels
       };
 
       //New up a credentials object and set the token
       imageryMetadataRequest.Credentials = new VEImageryService.Credentials();
       imageryMetadataRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
       // Create the ImageryServiceClient
       ImageryServiceClient imageryServiceClient = new ImageryServiceClient();
 
       //and make the request
       ImageryMetadataResponse imageryMetadataResponse = imageryServiceClient.GetImageryMetadata(imageryMetadataRequest);
 
       // Write out the tile metadata to the UI
       foreach (ImageryMetadataResult imageryMetadataResult in imageryMetadataResponse.Results)
       {
           Image image = new Image();
           image.ImageUrl = imageryMetadataResult.ImageUri;
           this.PlaceHolder_MapImages.Controls.Add(image);
 
           this.WritePair("Image URI", imageryMetadataResult.ImageUri);
           if (imageryMetadataResult.Vintage != null)
           {
               this.WritePair("Vintage From", imageryMetadataResult.Vintage.From.ToString());
               this.WritePair("Vintage To", imageryMetadataResult.Vintage.To.ToString());
           }
           this.WritePair("Zoom Range From", imageryMetadataResult.ZoomRange.From.ToString());
           this.WritePair("Zoom Range To", imageryMetadataResult.ZoomRange.To.ToString());
           this.WriteInfo("");
       }
   }

And finally add a handler for the button click

/// <summary>Writes a name/value pair to the UI, name is bolded.</summary>
    /// <param name="name">Name of the name/value pair</param>
    /// <param name="value">Value of the name/value pair</param>
    protected void WritePair(string name, string value)
    {
        this.WriteInfo("<B>" + name + ":</B> " + value);
    }
 
    /// <summary>Writes information to the UI</summary>
    /// <param name="html">HTML to write to the UI</param>
    protected void WriteInfo(string html)
    {
        this.Div_Info.InnerHtml += html + "<br/>\n";
    }

and Bam there you have a map coming at you from a longitude latitude and you are spitting out the the map tiles information.

If you need to do this from a address look at this example.

http://blog.geoffreyemery.com/post/Virtual-Earth-Web-Services----GeoCoding-and-Reverse-GeoCoding.aspx

After you geocode it you can then send in another request to get a map.

Download the code here.

image

One Last look at the finished Product

image


Virtual Earth Web Services - GeoCoding and Reverse GeoCoding

January 21, 2009 22:11 by gemery

In this tutorial we are going to look at what you need to go from a a Address to a Lat Long(GeoCode) and from a Lat Long to a Address(reverse geocode)

First a picture of what the final project will look like.

image

Note:

You must!  change the username in the web.config

    <add key="VEUsername" value="YourKey"/>
    <add key="VEPassword" value="YourPassword"/>

with your information

image

 

1) Learn about Tokens

Okay, so, first things first, you need to authenticate - see my post Authentication and Tokens with Virtual Earth for authentication.

 

2) Create a blank AJAX project in VS

Now that you are dialed in with your virtual earth tokens we are going to dive right into the web services. Lets go ahead and create a blank project in VS

3) Add the UI

I am going to spice this up a bit and make it Ajax enabled. So go ahead and install AJAX or if you are using VS2008 sp 1 you should be already cool. So go ahead and through a script manager down and a update panel, and a update progress manager down on the page. This is the web form should look like in between the body tags should look this now.

 

<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <asp:UpdateProgress ID="UpdateProgress1" runat="server" AssociatedUpdatePanelID="UpdatePanel1" DisplayAfter="5">
           <ProgressTemplate>
              
           </ProgressTemplate>
       </asp:UpdateProgress>
       <asp:UpdatePanel ID="UpdatePanel1" runat="server">
           <ContentTemplate>
     
           </ContentTemplate>
       
       </asp:UpdatePanel>

4 ) Add page propeties

Now are going to add our table to the update content template

<table border="1">
                    <tr>
                        <td valign="top">
                            Address: <asp:TextBox runat="server" ID="TextBox_Address" Width="250" />
                            <br />
                            <asp:Button runat="server" Text="Geocode" ID="Button_Geocode" 
                                onclick="Button_Geocode_Click" />
                        </td>
                        <td>
                            Latitude: <asp:TextBox runat="server" ID="TextBox_Latitude" Width="250" />
                            <br />
                            Longitude: <asp:TextBox runat="server" ID="TextBox_Longitude" Width="250" />
                            <br />
                            <asp:Button runat="server" Text="Reverse Geocode" ID="Button_ReverseGeocode" 
                                onclick="Button_ReverseGeocode_Click" />
                        </td>
                    </tr>
                </table>
                <br />

then add a div we are going to inject our information that we get back from Virtual Earth

<div runat="server" id="Div_Info" />

 

5) Add a web reference to the VE Geocode Service

Now are going to add a web reference to the VE Geocode Service

This is the address at the time of writing this article


http://staging.dev.virtualearth.net/webservices/v1/geocodeservice/geocodeservice.svc?wsdl

In our service refrence we now will have something that looks like this

image

Sweet that was easy.

6) Add a Utility class

Now that we have that we need to add a Utility class that will take our developer credentials and get us a token so we can start making requests against the web service api..

Here is a great  class for doing that.. I named it Utils.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.ServiceModel;
using VEWebServicesDemo.VEAuthenticationService;
using VEWebServicesDemo.VEGeocodeService;
using System.Configuration;
using System.Collections;
using System.Text.RegularExpressions;
 
namespace VEWebServicesDemo
{
    public static class Utils
    {
        private static string GetVEUsername() { return ConfigurationManager.AppSettings["VEUsername"].ToString(); }
        private static string GetVEPassword() { return ConfigurationManager.AppSettings["VEPassword"].ToString(); }
 
        public static string StripHTMLTags(string HtmlToStrip)
        {
            return Regex.Replace(HtmlToStrip, @"<(.|\n)*?>", string.Empty);
        }
 
        /// <summary>Returns a token from the Virtual Earth web service</summary>
        public static string Token(string ClientIP)
        {
            // This token will expire so that should be handled appropriately
            
                // Create a CommonService so we can make the request
                CommonService commonService = new CommonService
                {
                    // Supply your Virtual Earth credentials
                    // to get a Virtual Earth developer account, go to https://mappoint-css.live.com/MwsSignup/
                    Credentials = new NetworkCredential(Utils.GetVEUsername(), Utils.GetVEPassword())
                };
 
                // Create a token specification
                TokenSpecification tokenSpecification = new TokenSpecification
                {
                    // Token will expire in 60 minutes, max is 480 minutes
                    TokenValidityDurationMinutes = 60,
                    // Supply the client's IP address
                    ClientIPAddress = ClientIP
                };
                return commonService.GetClientToken(tokenSpecification);
          }
    }
}

Great so we have our auth service and we have our credentials class lets get into the fun stuff.

7) Give it Guts

Now have our front end our data access layer lets set up the middlish tier

First thing I am going to do is load up the page with some default values in the page_load so that when i demo this it I can click and show .

protected void Page_Load(object sender, EventArgs e)
   {
       // Set a default address to search for.
       if (this.IsPostBack == false)
       {
           // Default for the address box
           this.TextBox_Address.Text = "1313 S Figueroa St, Los Angeles, California 90015, United States";
 
           //LACC
           this.TextBox_Latitude.Text = "34.0404";
           this.TextBox_Longitude.Text = "-118.2688";
 
       }
   }

 

Next I am going to add functionality to the button to get a gecode from a address all information on the function are in the comments

/// <summary>Geocodes the address specified in the UI</summary>
       /// <param name="sender">The sender</param>
       /// <param name="e">Event arguments</param>
       protected void Button_Geocode_Click(object sender, EventArgs e)
       {
           // Clear any existing data from our div
           this.Div_Info.InnerHtml = "";
 
           GeocodeRequest geocodeRequest = new GeocodeRequest();
           
           // Create a new Credential object and provide the token
           geocodeRequest.Credentials = new VEGeocodeService.Credentials();
           geocodeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
           // Set the address from the UI on the request
           geocodeRequest.Query = this.TextBox_Address.Text.Trim();
 
           // Create a new geocode client
           GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient();
 
           // Execute the geocode request
           GeocodeResponse geocodeResponse = geocodeServiceClient.Geocode(geocodeRequest);
 
           // Iterate through each of the results and send write some data to the UI
           foreach (GeocodeResult geocodeResult in geocodeResponse.Results)
           {
               this.WritePair("Formatted Address", geocodeResult.Address.FormattedAddress);
               this.WritePair("Display Name", geocodeResult.DisplayName);
               this.WritePair("Confidence", geocodeResult.Confidence.ToString());
 
               // Iterate through each location within the result and send back the Lat/Long
               foreach (GeocodeLocation geocodeLocation in geocodeResult.Locations)
               {
                   this.WritePair("Calculation Method", geocodeLocation.CalculationMethod);
                   this.WritePair("Longitude", geocodeLocation.Latitude.ToString());
                   this.WritePair("Latitude", geocodeLocation.Longitude.ToString());
               }
               this.WriteInfo("");
           }
       }

I am going to add the reverse geocode functionality

 

/// <summary>Reverse geocodes the latatitude and longitude specified in the UI</summary>
        /// <param name="sender">The sender</param>
        /// <param name="e">Event arguments</param>
        protected void Button_ReverseGeocode_Click(object sender, EventArgs e)
        {
            // Clear any existing data from our div
            this.Div_Info.InnerHtml = "";
 
            //Create a new ReverseGeoCode Request object
            ReverseGeocodeRequest reverseGeocodeRequest = new ReverseGeocodeRequest();
 
            // Create a new Credential object and provide the token
            reverseGeocodeRequest.Credentials = new VEGeocodeService.Credentials();
            reverseGeocodeRequest.Credentials.Token = Utils.Token(Request.UserHostAddress);
 
            //New a VEGeocode Location object and set it's properties
            reverseGeocodeRequest.Location = new Location
            {
                Latitude = Convert.ToDouble(this.TextBox_Latitude.Text),
                Longitude = Convert.ToDouble(this.TextBox_Longitude.Text)
            };
 
            // New up a new GeocodeServiceClient to make our request with
            GeocodeServiceClient geocodeServiceClient = new GeocodeServiceClient();
 
            // Execute the ReverseGeocode request
            GeocodeResponse geocodeResponse = geocodeServiceClient.ReverseGeocode(reverseGeocodeRequest);
 
            // Write out the response information to the UI
            foreach (GeocodeResult geocodeResult in geocodeResponse.Results)
            {
                this.WritePair("Display Name", geocodeResult.DisplayName);
                this.WritePair("Entity Type", geocodeResult.EntityType);
                this.WritePair("Confidence", geocodeResult.Confidence.ToString());
                this.WritePair("Address Line", geocodeResult.Address.AddressLine);
                this.WritePair("Locality (city)", geocodeResult.Address.Locality);
                this.WritePair("Admin District (state)", geocodeResult.Address.AdminDistrict);
                this.WritePair("Postal Code", geocodeResult.Address.PostalCode);
                this.WriteInfo("");
            }
        }

 

A couple of little helper functions

// <summary>Writes a name/value pair to the UI, name is bolded.</summary>
        /// <param name="name">Name of the name/value pair</param>
        /// <param name="value">Value of the name/value pair</param>
        protected void WritePair(string name, string value)
        {
            this.WriteInfo("<B>" + name + ":</B> " + value);
        }
 
        /// <summary>Writes information to the UI</summary>
        /// <param name="html">HTML to write to the UI</param>
        protected void WriteInfo(string html)
        {
            this.Div_Info.InnerHtml += html + "<br/>\n";
        }
    }

And Bam we have a working demo. 7 Steps to Virtual Earth Web Services.

Here is a shot of the what the reverse geocode spits out

image 

image

Have Fun!