Hi !
Today i'll talking about GeoLocation / GeoTargeting with ASP.NET.
I based my article with the Scott Hanselman's article who provides a simple way to do GeoLocation from an IPAddress using the HostIp API.
So i decided to make this more flexible using the Provider Pattern in order to change/switch easly from GeoLocation Provider.
Using this GeoLocation Provider Based API you can easly configure your ASP.NET Application to use severals GeoLocation Online Providers like HostIP.
The provider provides a GetLocationInfo() method which returns a populated GeoLocationInfo Object.
public class GeoLocationInfo
{
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; }
}
GeoLocationProvider is an Abstract Class so you need to implements the GetLocationInfo() method with your Provider specifics.
#region Public Abstract Methods
public abstract GeoLocationInfo GetLocationInfo(string ipParam);
#endregion
All Requested IPAddresses are Cached in a Static Dictionnary in the GeoLocationProvider for performance issue.
#region Public Properties
public static Dictionary<string, GeoLocationInfo> CachedIps
{
get;
set;
}
#endregion
Here is a sample of implementation using HostIP API.
public class HostIpProvider : GeoLocationProvider
{
public override GeoLocationInfo GetLocationInfo(string ipParam)
{
GeoLocationInfo geo = new GeoLocationInfo();
GeoLocationInfo 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));
}
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 GeoLocationInfo
{
CountryCode = x.Element(ns + "countryAbbrev").Value,
CountryName = x.Element(ns + "countryName").Value,
Name = x.Element(gml + "name").Value
}).SingleOrDefault();
var coord = (from p in xmlResponse.Descendants(ns + "Hostip")
where p.Element(gml + "coordinates").HasElements
&& p.Element(gml + "coordinates").HasElements
select new GeoLocationInfo
{
Latitude = float.Parse(p.Descendants(gml + "coordinates")
.Single().Value.Split(',')[0]),
Longitude = float.Parse(p.Descendants(gml + "coordinates")
.Single().Value.Split(',')[1])
}).SingleOrDefault();
result.Latitude = coord.Latitude;
result.Longitude = coord.Longitude;
}
catch (NullReferenceException)
{
//Looks like we didn't get what we expected.
}
if (result != null)
{
CachedIps.Add(ip, result);
}
}
else
{
result = CachedIps[ip];
}
return result;
}
}
You can now easly configure your providers in the web.config like that
<configuration>
<configSections>
<section name="GeoLocation" type="GeoLocation.GeoLocationConfigurationSection, GeoLocalisation" />
</configSections>
<GeoLocation defaultProvider="HostIpProvider">
<providers>
<add name="HostIpProvider" type="GeoLocation.HostIpProvider" />
</providers>
</GeoLocation>
</configuration>
The usage of this Provider is pretty simple like this
string ipaddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
GeoLocationInfo info = GeoLocation.Provider.GetLocationInfo(ipaddress);
Hope this article help's!
Download Solution - GeoLocalisation.zip
Views(1454)

