How to dynamically serve a KML file in Asp.net 2.0

Posted on August 06, 2007

KML is the markup language that Google uses to represent markers in Google Earth – and NOW in Google Maps!

How it works, is that you store the KML in a file on a web server where Google can get at it. Google then goes at caches the file, and generates the output map markers.

But what if you want to display dynamic markers using KML?

Here’s how:

First add an aspx page to your project. This will be the page to serve the KML.

Create an xml document that will represent the kml file using the XmlDocument class. Should look something like this:
XmlDocument xmlDoc = new XmlDocument();

XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0","utf-8",null); 

// Create the root element
XmlElement rootNode  = xmlDoc.CreateElement("kml");
rootNode.SetAttribute("xmlns", @"http://earth.google.com/kml/2.1");
xmlDoc.InsertBefore(xmlDeclaration, xmlDoc.DocumentElement); 
xmlDoc.AppendChild(rootNode);
XmlElement documentNode = xmlDoc.CreateElement("Document");
rootNode.AppendChild(documentNode);

XmlElement iconNode = xmlDoc.CreateElement("Icon");
XmlElement iconHrefNode = xmlDoc.CreateElement("Href");
XmlText iconHrefText = xmlDoc.CreateTextNode("marker_image.gif");
iconHrefNode.AppendChild(iconHrefText);
iconNode.AppendChild(iconHrefNode);

documentNode.AppendChild(iconNode);

// MyMarkerClass is my own object used to hold my internal longlat stuff - replace with your own mechanism here
foreach (MyMarkerClass marker in markers)
{
  // Create a new <Placemark> element and add it to the root node
  XmlElement placeMarkNode = xmlDoc.CreateElement("Placemark");
  documentNode.AppendChild(placeMarkNode);

  // Create the required nodes
  XmlElement nameNode = xmlDoc.CreateElement("name");
  XmlText nameText = xmlDoc.CreateTextNode(marker.Name);
  placeMarkNode.AppendChild(nameNode);
  nameNode.AppendChild(nameText);
  XmlElement descNode = xmlDoc.CreateElement("description");                
  XmlText descriptionText = xmlDoc.CreateTextNode(marker.Description);                
  placeMarkNode.AppendChild(descNode);
  descNode.AppendChild(descriptionText);

  XmlElement pointNode = xmlDoc.CreateElement("Point");
  placeMarkNode.AppendChild(pointNode);

  XmlElement coordsNode = xmlDoc.CreateElement("coordinates");
  XmlText coordsText = xmlDoc.CreateTextNode(string.Format("{0},{1},{2}", marker.Long, marker.Lat, 0));
  pointNode.AppendChild(coordsNode);
  coordsNode.AppendChild(coordsText);                
}
Then, in your Page_Load method, write the KML directly to the output like this:
Response.ContentType = "application/x-msdownload";

XmlTextWriter writer = new XmlTextWriter(Response.OutputStream, null);
xmlDoc.WriteTo(writer);
writer.Flush();

Almost there! Now you’ll need to rewrite the url so that Google can try and find it with an innocuous “myfile.kml” path. We created a url rewriting method in house, but there are tutorials on line on how to do it (try here or here )

Now all you need to do is include the url rewritten kml path in your javascript, and Google will use it beautifully!

Prevent an asp.net button from doing a postback

Posted on July 25, 2007

Something that bugged me for ages in asp.net was how to prevent an asp.net button from automatically doing a postback.

To prevent a postback occuring simply make the OnClientClick event return false like this:

<asp:Button ID="button" runat="server" OnClientClick='return false' />

QuickSwitch for VS 2003

Posted on July 18, 2007

Lars Engel updated my Visual Studio QuickSwitch plugin so it can now work on Visual Studio 2003.

Not only that, but he made it even better – now you hit a checkbox to search through all open projects as well (not just the current project.)

Find his blog post here:Quick Switch for Visual Studio 2003 / .NET 1.1 where he also keeps binaries of the updated files.

Thanks Lars!

Open files without leaving the keyboard in Visual Studio

Posted on July 02, 2007

At the Developer Developer Developer day on Saturday I saw a great presentation done by Zi Makki on how to create Visual Studio plugins.

After the conference, I immediately ran home and started work on a plugin to fix a current pain of mine: the ability to quickly open files in Visual Studio without using the mouse.

Using Textmate on the mac, there’s a really neat fast system for switching files. You simply hit Command – T and up pops this dialog:

.

Then you simply type a portion of the file name and the results list is filtered. Hit enter and you’ve opened it up real fast!

So, I made a quick and dirty version of this for Visual Studio. It’s called QuickSwitch

Installation

1) First you need the DXCore – this is a FREE download from devexpress. Download it here and install it on your machine (you probably have to close down Visual Studio first).


2) Next, download this file QuickSwitch.zip and extract the contents into this folder (or wherever you installed DXCore):

c:\Developer Express Inc\DXCore for Visual Studio .NET\2.0\Bin\Plugins

3) Open up Visual Studio and you’ll have a new menu bar at the top DevExpress. Click this menu item and hit Options. On the options screen, add a new Keyboard Shortcut and type “Quick Switch” in the command textbox.. In the key sequence use a key sequence you want to use for this (I use Ctrl T)

Ok, now you’re ready to use it!

Using Quick Switch

Open up a solution. Hit the Quick Switch shortcut key. You’ll be greeted with this dialog listing all the files in the current project (files with the same name will have their folder names prefixed):

Start typing (no need to take your hands off the keyboard!) and the file list down the bottom will change.

Hit [enter] to automatically open the top file, or hit up and down to select a different file.

Voila – the file is opened!

Much faster than using the solution explorer!

(Yet another note: you can download the source for this plugin here)

UPDATE Rather annoyingly this version only works in Visual Studio 2005 – sorry 2003 fans!

Easy trick to speed up Visual Studio 2005

Posted on June 28, 2007

I found this on a Microsoft Forum Posting – apparently the navigation bar was slowing things down a bit – and if you’re anything like me, you never use it anyway.

The navigation bar is this thing at the top:

Go to Tools > Options > Text Editor > C# and click the Navigation Bar check box.

You should notice a speed boost when you type code or use intellisense!

(Be sure to turn it off for HTML if you use Asp.net as well. Tools > Options > Text Editor > HTML)

(I haven’t proved scientifically that this speeds things up yet…)

Snippet in Visual Studio to create static method

Posted on June 27, 2007

After using Textmate for a couple of weeks I’ve come to realise how incredibly powerful and beautiful it is! Creating text snippets is a breeze – and improves productivity no end!

To achieve the same affect in Visual Studio though is a right pain in the butt-ocks. All I wanted to do was create a very basic snippet to define a static method (because I was creating a bunch of them all at the same time) and had to get down and dirty with some XML.

Anyhoo – here’s my result:

<?xml version="1.0" encoding="utf-8" ?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>Public Static Method Declaration</Title>
      <Shortcut>pubs</Shortcut>
      <Description>Code snippet for creating a static method</Description>
      <Author>Chris O'Sullivan</Author>
      <SnippetTypes>
        <SnippetType>Expansion</SnippetType>
      </SnippetTypes>
    </Header>
    <Snippet>
      <Declarations>
        <Literal>
          <ID>return_type</ID>
          <ToolTip>Return Type</ToolTip>
          <Default>void</Default>
        </Literal>
        <Literal>
          <ID>method_name</ID>
          <ToolTip>Method Name</ToolTip>
          <Default>method</Default>
        </Literal>
        <Literal>
          <ID>param_type</ID>
          <ToolTip>Param Type</ToolTip>
          <Default>param_type</Default>
        </Literal>
        <Literal>
          <ID>param</ID>
          <ToolTip>Name of Param</ToolTip>
          <Default>param</Default>
        </Literal>
      </Declarations>
      <Code Language="csharp">
        <![CDATA[public static $return_type$ $method_name$($param_type$ $param$)
            {
            }
          ]]>
        </Code>
      </Snippet>
    </CodeSnippet>
    </CodeSnippets>
Then you just type pubs[tab] and it will create a declation like this:
public static void method(param_type param)
{
}

With the ability to tab between the different fields.

But oh man what a pain that was to do! (I love you textmate – xx)

Enumerating through .Net enums

Posted on June 18, 2007

So, I was working on something that required a loop through enumerated types (in this case, go through the different repayment methods of a mortgage calculator)

public enum RepaymentMethod
 {
     RepaymentOnly ,
     InterestOnly,
     MixOfBoth,
 }

To loop through this, use Enum.GetValues() to grab an array of the enumerations, and walk through it like this:

Array repaymentMethods = Enum.GetValues(typeof(RepaymentMethod));
foreach (RepaymentMethod method in repaymentMethods)
{
  calculator.RepaymentMethod = method;
  calculator.doStuff();   
  Assert.AreEqual(0, calculator.MonthlyPayments);
}

Free dotnet profiler

Posted on June 15, 2007

So yesterday I was working on an application that was going ridiculously slow and I couldn’t figure out why. That’s when I used the open source program nprof to profile my application to see where the bottlenecks are! (Download it here )

According to the documentation, this can also be used to profile web apps too!

It’s really easy to use. Open nprof exe

Input your executable path into the Application textbox (and any command line args in the Arguments textbox) and then hit F5. This will spawn a copy of your app that you can use normally. After the application successfully closes then you get a list of what methods were called during the running of the app and what percent of application time was spent in that application e.g:

Also on the left hand side in the Runs list you can see previous times you’ve run the program in the profiler – allowing you to make comparisons to see what methods are currently slowing you down.

Pretty cool!

Beautifully format your .net source code in seconds!

Posted on June 02, 2007
Ok, so you're creating a beautiful .aspx page - and then you flip to design mode to use an auto tag or something. You flip back to the source and WHAMMO your beautiful layout has been messed up by the stinking asp.net design mode!

So, you spend the next 5 minutes wasting your life by ensuring all the div tags etc line up...

OR

You hit Ctrl K then Ctrl D and in seconds your code is wonderfully, beautifully, elegantly laid out!

Fantastic!

This works on code-behind files as well

Better structured Selenium Tests

Posted on May 28, 2007
Selenium is a fantastic tool developed by ThoughtWorks for automated web acceptance tests.

If you're a web developer and you've never used this tool, go check it out immediately!

How I've been generally Selenium is by using the Selenium IDE Firefox Plugin to record my tests - and then copying the automatically generated C# into my test classes.

This is a really quick and easy approach, however the test code get's REALLY ugly REALLY fast.

Then I saw Erik Doernenburg's excellent presentation on Selenium best practices, and heard a great tip that's so simple and elegant I felt stupid for not thinking about it before.
Create a class for each of your web pages and use static methods to wrap the Selenium code. This allows you to create nice, human readable tests that are also far less brittle.
MainPage.cs (C#)
public class MainPage
{
    public static void Open()
    {
      Selenium.Open(@"/");
    }

    public static void SearchFor(string searchString)
    {
      // Ugly brittle code nicely wrapped up
      Selenium.Type("txtSearch", searchString);
      Selenium.Click("btnSubmit");
      Selenium.WaitForPageToOpen("30000")
    }
   
    public static int NumberOfSearchResults()
    {
      // This function uses regex to return the number of results on the page
      ..
    }
}
And then in your unit test class:
MainPageUnitTests.cs (C#)
   [Test]
   public void TestForSearch()
   {
     // Nice readable test logic
     MainPage.Open();
     MainPage.SearchFor("bananas");
     Assert.AreEqual(1, MainPage.NumberOfSearchResults(), "Wrong number of results");
   }

Batch Insert of Records in .Net

Posted on May 27, 2007
So, I've got a DataTable behind the scenes practically packed with data (1000s of rows) - and I want to insert this into a table on sql server using a stored procedure. The wrong way:
//The dsSourceDataSet is a populated dataset with1 table with tonnes of rows
foreach (DataRow row in dsSourceDataSet[0].Rows)
{
  SqlCommand command = new SqlCommand("sp_my_proc", connection)
  command.Parameters.AddWithValue("@param1", row["field1"].Value);
  command.Parameters.AddWithValue("@param2", row["field2"].Value);
  //Yada yada
  command.ExecuteNonQuery();
}
I mean, let's face it - this works so I thought "Hey, that's good enough for me!" But man was it sloooow! Then my boss showed me the CORRECT way of doing things: The right way:
SqlCommand command = new SqlCommand("sp_my_proc", oConnSource);
SqlDataAdapter dataAdapter = new SqlDataAdapter(command);
SqlParameter param1 = dataAdapter.InsertCommand.Parameters.Add("@param1", SqlDbType.VarChar);
param1 .SourceColumn = "field1";
param1 .SourceVersion = DataRowVersion.Original;
dataAdapter.Update(dsSourceDataSet);
So what's happening? Instead of looping through the table like a crazy gooloot - everything gets crammed into the dataset and fired off to the database! And it is SOOO much faster! This process took a little over an hour before, now it takes a few minutes! Hooray!

Automatically load the Asp.net Web Server

Posted on May 27, 2007
When I'm debugging my Asp.net applications, I find myself just wanting a quick and easy way of starting the asp.net web server. You can do this from the command line like this:
"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\WebDev.WebServer.exe" /path:[PATH OF YOUR WEB APP] /port:[WEB PORT]  /vpath:[/mywebapp]

You can also use the funky explorer plug-in designed by Robert McClaws here. This lets you run the webserver just by right clicking on a folder path.