Scott Hanselman

The Weekly Source Code 37 - Geolocation/Geotargeting (Reverse IP Address Lookup) in ASP.NET MVC made easy

November 27, '08 Comments [24] Posted in ASP.NET | ASP.NET MVC | Source Code
Sponsored By

First, let me remind you that in my new ongoing quest to read source code to be a better developer, Dear Reader, I present to you thirty-seventh in a infinite number of posts of "The Weekly Source Code."

I'm working on a side-project with Rob Conery, Dave Ward and others and I want to be able to do a search immediately as the user arrives on the site, using their location derived from their IP Address. I want to use "Geolocation" or Reverse IP Address Lookup, and take an IP like 127.0.0.1 and turn it into "New York, NY."

There are lots of services and databases that you can buy that will let you make a web service call and get back a location. Some will include latitude and longitude, some include the city name. Some are REALLY expensive, like $500 or more.

I found two solutions, one server-side that's a community project and one client-side from Google!

Community-based Geotargeting from hostip.info

If you hit http://www.hostip.info/ with your browser, it'll guess where you are and show a map with your estimated location, usually within 50-100 miles. It's a community-based project with a freely available database. They've got over 8.6 million entries in their database!

More interestingly, they have a nice clean API for Geotargeted IP Address Lookup.

For example:

http://api.hostip.info/get_html.php?ip=12.215.42.19&position=true
  Country: UNITED STATES (US)
  City: Sugar Grove, IL
  Latitude: 41.7696
  Longitude: -88.4588

if you add just call:

http://api.hostip.info/?ip=12.215.42.19

You'll get an XML document back with lots of good information.

So, I wrote a quick .NET wrapper for this service. Note the sample XML file in the comment in the middle there. I also put in a default location for debugging. It's not the cleanest code in the world, but LINQ to XML made it easy and it either works or it doesn't.

public class LocationInfo
{
public float Latitude { get; set; }
public float Longitude { get; set; }
public string CountryName { get; set; }
public string CountryCode { get; set; }
public string Name { get; set; }
}

public class GeoLocationService
{
public static LocationInfo GetLocationInfo()
{
//TODO: How/where do we refactor this and tidy up the use of Context? This isn't testable.
string ipaddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
LocationInfo v = new LocationInfo();

if (ipaddress != "127.0.0.1")
v = GeoLocationService.GetLocationInfo(ipaddress);
else //debug locally
v = new LocationInfo()
{
Name = "Sugar Grove, IL",
CountryCode = "US",
CountryName = "UNITED STATES",
Latitude = 41.7696F,
Longitude = -88.4588F
};
return v;
}

private static Dictionary<string, LocationInfo> cachedIps = new Dictionary<string, LocationInfo>();

public static LocationInfo GetLocationInfo(string ipParam)
{
LocationInfo result = null;
IPAddress i = System.Net.IPAddress.Parse(ipParam);
string ip = i.ToString();
if (!cachedIps.ContainsKey(ip))
{
string r;
using (var w = new WebClient())
{
r = w.DownloadString(String.Format("http://api.hostip.info/?ip={0}&position=true", ip));
}

/*
string r =
@"<?xml version=""1.0"" encoding=""ISO-8859-1"" ?>
<HostipLookupResultSet version=""1.0.0"" xmlns=""http://www.hostip.info/api"" xmlns:gml=""http://www.opengis.net/gml"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xsi:schemaLocation=""http://www.hostip.info/api/hostip-1.0.0.xsd"">
<gml:description>This is the Hostip Lookup Service</gml:description>
<gml:name>hostip</gml:name>
<gml:boundedBy>
<gml:Null>inapplicable</gml:Null>
</gml:boundedBy>
<gml:featureMember>
<Hostip>
<gml:name>Sugar Grove, IL</gml:name>
<countryName>UNITED STATES</countryName>
<countryAbbrev>US</countryAbbrev>
<!-- Co-ordinates are available as lng,lat -->
<ipLocation>
<gml:PointProperty>
<gml:Point srsName=""http://www.opengis.net/gml/srs/epsg.xml#4326"">
<gml:coordinates>-88.4588,41.7696</gml:coordinates>
</gml:Point>
</gml:PointProperty>
</ipLocation>
</Hostip>
</gml:featureMember>
</HostipLookupResultSet>";
*/

var xmlResponse = XDocument.Parse(r);
var gml = (XNamespace)"http://www.opengis.net/gml";
var ns = (XNamespace)"http://www.hostip.info/api";

try
{
result = (from x in xmlResponse.Descendants(ns + "Hostip")
select new LocationInfo
{
CountryCode = x.Element(ns + "countryAbbrev").Value,
CountryName = x.Element(ns + "countryName").Value,
Latitude = float.Parse(x.Descendants(gml + "coordinates").Single().Value.Split(',')[0]),
Longitude = float.Parse(x.Descendants(gml + "coordinates").Single().Value.Split(',')[1]),
Name = x.Element(gml + "name").Value
}).SingleOrDefault();
}
catch (NullReferenceException)
{
//Looks like we didn't get what we expected.
}
if (result != null)
{
cachedIps.Add(ip, result);
}
}
else
{
result = cachedIps[ip];
}
return result;
}
}

I did put some naive caching in here. I would probably put in some cleanup so the cache could only get so big, maybe a few thousand IPs. Perhaps a FIFO queue, where I start yanking the old stuff after it gets full. Or, use the ASP.NET Cache and just let it manage memory and eject stuff that hasn't been touched in awhile.

This worked great for a while, but at some point, if my site became successful I'd want to send these guys money, or regularly download their free Geolocation database and run the whole thing locally.

Then, while looking at Google's Ajax Libraries API site as a place for my site to download the jQuery libraries rather than me hosting them, I noticed…

Free Geotargeting is built into Google's AJAX Libraries API

Google offers a free service called google.load that lets you load your favorite Javascript APIs using Google's Javascript Loader API, rather than hosting them locally. This means that you and your site get a few excellent benefits:

    • The files are loaded fast because they are on Google's CDN (Content Distribution Network)
    • The files are loaded asynchronously by newer browsers because they aren't stored on your site (most browsers open up to 6 HTTP connections per DNS/site, but older ones do 2.
      • This is why back in the 90's we had www.800.com and images.800.com in order to get some parallelizm. It's also recommended by YSlow, although you should balance this knowledge remembering that there's a cost for a DNS lookup. That said, newer browsers like Chrome include their own local DNS cache which mitigates that issue. Moral of the story? Know all this stuff, but know that it'll all be obsolete and moot soon. ;)
    • They offer a versioning API, so you can say, "get me version 2 of something" you'll get 2.24 if it's the latest.

What does this have to do with Geotargeting? Well, you know when you get Google.com they know where you are. They'll offer Spanish if you're in Spain. Since they ALREADY know this stuff, they are making in available to your script via google.loader.ClientLocation for free. They announced this in August and I missed it until today!

I'm doing this:

<script src="http://www.google.com/jsapi?key=YOURAPIKEY" type="text/javascript"></script>
<script>
google.load("jquery", "1.2.6");
google.load("jqueryui", "1.5.2");
var yourLocation = google.loader.ClientLocation.address.city + ", "
+ google.loader.ClientLocation.address.region;
</script>

Note that you need to sign up for a free API KEY for your domain so they can contact you if there's a problem with the script.

Later on, I use the yourLocation JavaScript variable and put it in a Search Box for my app and go searching based on your location. If your location is wrong, I remember if you typed in a different city in the Search Box and I'll use that again, so I only annoy you once.

If that's not enough information, you can use the proper Geolocation API, which is much more sophisticated but requires Google Gears.

Enjoy!

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 138 - Paint.NET with Rick Brewster

November 25, '08 Comments [5] Posted in Deployment | Podcast
Sponsored By

PAINT.NET Logo My one-hundred-and-thirty-eighth podcast is up.

Well, actually a few weeks ago, but I totally forgot to update my website with the details. You'd think somewhere around 100 shows I'd had automated this somehow. Hm. If I only I know a programmer and the data was available in some kind of universal structure syndication format…;)

Scott talks with Paint.NET author Rick Brewster about some of the internals of his popular freeware application. They focus on deployment and setup, how Rick does it and what we can learn from him.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show!

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 137 - Microsoft PDC and Windows 7 Reaction Show with Richard Campbell

November 25, '08 Comments [1] Posted in PDC | Podcast
Sponsored By

richard_headshot_web My one-hundred-and-thirty-seventh podcast is up.

Well, actually a few weeks ago, but I totally forgot to update my website with the details. You'd think somewhere around 100 shows I'd had automated this somehow. Hm. If I only I know a programmer and the data was available in some kind of universal structure syndication format…;)

Scott catches up with Richard Campbell at DevConnections in Las Vegas and they chat about the announcements at the 2008 Microsoft PDC and how/if the new stuff will affect our lives.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show!

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 136 - MSR@PDC - Microsoft Research at the Professional Developers Conference

November 25, '08 Comments [0] Posted in PDC | Podcast
Sponsored By

My one-hundred-and-thirty-sixth podcast is up.

Well, actually a few weeks ago, but I totally forgot to update my website with the details. You'd think somewhere around 100 shows I'd had automated this somehow. Hm. If I only I know a programmer and the data was available in some kind of universal structure syndication format…;)

One of the hidden gems this year at the PDC conference was the Microsoft Research section. It was buried in the back of the convention center, unfortunately, so a lot of people didn't know it was there. Scott talks to each team at length and gets the scoop on what project are coming to an IDE near you sometime soon.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show!

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Hanselminutes Podcast 135 - StackOverflow Behind The Music - Unedited Outtakes Show

November 25, '08 Comments [7] Posted in ASP.NET | ASP.NET MVC | Podcast
Sponsored By

My one-hundred-and-thirty-fifth podcast is up.

Well, actually a few weeks ago, but I totally forgot to update my website with the details. You'd think somewhere around 100 shows I'd had automated this somehow. Hm. If I only I know a programmer and the data was available in some kind of universal structure syndication format…;)

Here's some raw audio from the last show. We left the recorder on after the show was over, and the discussion continued for another 30 minutes! It's a different conversation in a raw style, but we hope you enjoy it.

Subscribe: Subscribe to Hanselminutes Subscribe to my Podcast in iTunes

Do also remember the complete archives are always up and they have PDF Transcripts, a little known feature that show up a few weeks after each show.

Telerik is our sponsor for this show!

Building quality software is never easy. It requires skills and imagination. We cannot promise to improve your skills, but when it comes to User Interface, we can provide the building blocks to take your application a step closer to your imagination. Explore the leading UI suites for ASP.NET and Windows Forms. Enjoy the versatility of our new-generation Reporting Tool. Dive into our online community. Visit www.telerik.com.

As I've said before this show comes to you with the audio expertise and stewardship of Carl Franklin. The name comes from Travis Illig, but the goal of the show is simple. Avoid wasting the listener's time. (and make the commute less boring)

Enjoy. Who knows what'll happen in the next show?

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.