Thursday 9 January 2014

GeoLocation - Get Country of IP Address

Sometimes in projects we build we need to add a level of localization. E.g. Some customers access sites from the UK and others from Ireland. Each site offers a different selection of products and the only way to truly ensure a customer can see the correct products for their location is to create a user account.

Although the Mechanism for creating a user account is simple for browsing a website - Customers do find this confusing as one minute the products are there and the next they are not.

So In this case we need to identify the Country by IP, There are many reasons why this could potentially fail however on the whole it catches most potential customers.

First I create a link to http://freegeoip.net/json/ and I append the IP Address onto the end of this.


private static readonly string GeolocationUrl = "http://freegeoip.net/json/212.58.244.66";


From this we get a JSON String that gives us the information pertaining to this IP Address.

{"ip":"212.58.244.66","country_code":"GB","country_name":"United Kingdom","region_code":"N7","region_name":"Surrey","city":"Tadworth","zipcode":"","latitude":51.2833,"longitude":-0.2333,"metro_code":"","area_code":""}


This indeed gives us a Country Code and Country Name from which we can parse and use for our application. The following method below is sufficient to return us an object called 'IpInformationLocation' The 'IpInformationLocation' object is rather simple, Its an object that we can use to build our data.

[Serializable]
public class IpLocationInformation
{
    [DefaultValue("")]
    public string IpAddress { get; set; }

    [DefaultValue("")]
    public string CountryCode { get; set; }

    [DefaultValue("")]
    public string CountryName { get; set; }

    [DefaultValue("")]
    public string RegionCode { get; set; }

        [DefaultValue("")]
        public string RegionName { get; set; }

        [DefaultValue("")]
        public string City { get; set; }

        [DefaultValue("")]
        public string ZipCode { get; set; }

        [DefaultValue("")]
        public string Latitude { get; set; }

        [DefaultValue("")]
        public string Longitude { get; set; }

        public IpLocationInformation() { }

        public IpLocationInformation(string json)
        {
            JObject jObject = JObject.Parse(json);

            //JToken jDataBlock = jObject[""];

            IpAddress = jObject["ip"].ToString();

            CountryCode = jObject["country_code"].ToString();
            CountryName = jObject["country_name"].ToString();
            RegionCode = jObject["region_code"].ToString();
            RegionName = jObject["region_name"].ToString();
            City = jObject["city"].ToString();
            ZipCode = jObject["zipcode"].ToString();
            Latitude = jObject["latitude"].ToString();
            Longitude = jObject["longitude"].ToString();
        }
        public override string ToString()
        {
            string theReturn = string.Format("@\n\n" +
                                             "IP Address: {0}\n" +
                                             "Country Code: {1}\n" +
                                             "Country Name: {2}\n" +
                                             "RegionCode: {3}\n" +
                                             "City: {4}\n" +
                                             "ZipCode: {5}\n" +
                                             "Latitude: {6}\n" +
                                             "Longitude: {7}\n\n", new object[] {IpAddress, CountryCode, CountryName, RegionCode, City, ZipCode,Latitude,Longitude});
            return theReturn;
        }
    }


We then create a method that uses the website above, Adds and IP Address then generates an IpLocationInformation object. We do this like so.

public IpLocationInformation GetLocationByIp(string ipAddress)

        {

            try

            {

                string formattedUri = string.Format(CultureInfo.InvariantCulture, GeolocationUrl, ipAddress);



                var webRequest = GetWebRequest(formattedUri);

                var response = (HttpWebResponse)webRequest.GetResponse();



                var jsonResponse = string.Empty;



                var stream = response.GetResponseStream();

                if (stream != null)

                {

                    var reader = new StreamReader(stream);



                    jsonResponse = reader.ReadToEnd();

                }



                var ipLocation = new IpLocationInformation(jsonResponse);



                return ipLocation;

            }

            catch (Exception)

            {

                throw new WebException("There was a problem processing this Request.  Please Check the Information which you are passing.");

            }

        }


After this we are able to use the method to deduce the location of the calling IP Address which can then give the user a customized version of the site.