IP Address Location In ASP.NET

Posted by: Suprotim Agarwal , on 5/29/2009, in Category ASP.NET
Views: 267557
Abstract: There are a lot of paid as well as free services that can find Visitor Geographical information from I.P Addresses. In this article, we will consume a free online API and fetch data using LINQ To XML.
IP Address Location In ASP.NET
 
There are a lot of paid as well as free services that can find Visitor Geographical information like country, region, city, latitude, longitude, ZIP code, time zone etc from I.P Addresses. http://iplocationtools.com/ip_location_api.php is one such free IP Geolocation API that returns geographical data in three formats: XML, JSON and CSV. In this article, we will consume this API and fetch visitor geographical information in XML format in the simplest possible way, using LINQ To XML.
Update: This service seems to be no longer working the way it was when i wrote this article. You can get more info over here and here
Using LINQToXML to consume data from an IP Address Location XML API
 
Using the IP Address Location XML API is quite simple. Just specify the I.P. address as shown below
http://iplocationtools.com/ip_query2.php?ip=74.125.45.100
and you will receive an XML document with the visitor geographical information in the following format:
<Locations>
 <Location id="0">
    <Ip>74.125.45.100</Ip>
    <Status>OK</Status>
    <CountryCode>US</CountryCode>
    <CountryName>United States</CountryName>
    <RegionCode>06</RegionCode>
    <RegionName>California</RegionName>
    <City>Mountain View</City>
    <ZipPostalCode>94043</ZipPostalCode>
    <Latitude>37.4192</Latitude>
    <Longitude>-122.057</Longitude>
 </Location>
</Locations>
Note: In order to specify multiple I.P(maximum 25), use a comma(,) separator as shown here: http://iplocationtools.com/ip_query2_country.php?ip=74.125.45.100,206.190.60.37
However as you can observe, this is not a very UI friendly format. So our next step is to parse the XML and apply some styling to it.
Now in .NET 2.0, if someone were to consume this API, a standard practice would have been to create a WebClient class and use a StreamReader object to read the data as shown below:
 C#
 
WebClient wc = new WebClient();
Stream data = wc.OpenRead(url);
String str;
using (StreamReader sr = new StreamReader(data))
{
    str = sr.ReadToEnd();
    data.Close();
}
 VB.NET
 Dim wc As New WebClient()
Dim data As Stream = wc.OpenRead(url)
Dim str As String
Using sr As New StreamReader(data)
      str = sr.ReadToEnd()
      data.Close()
End Using
 However in .NET 3.0, consuming this API using LINQToXML is quite simple. There are two ways to consume this API using LINQToXML - Using the XElement class or the XDocument class. Both the classes contain the ‘Load()’ method which accepts a file, a URL or XMLReader and allows XML to be loaded. The primary difference between both the classes is that an XDocument can contain XML declaration, XML Document Type (DTD) and processing instructions. Moreover an XDocument contains one root XElement.
For those who are not familiar with LINQToXML, I strongly suggest you to read my article Some Common Operations using LINQ To XML
We will use the XDocument class to consume the XML API in just two lines of code. I will demonstrate that in a bit. Let us first create a page layout to accept I.P Address and display data.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <style type="text/css">
        body
        {
        font: normal 11px auto "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;   
        background-color: #ffffff;
        color: #4f6b72;      
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
 
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:Panel ID="panelLoc" runat="server">
                    <asp:TextBox ID="txtIP" runat="server"></asp:TextBox>
                    <asp:Button ID="btnGetLoc"
                        runat="server" Text="Get IP Details" onclick="btnGetLoc_Click" />
                    <br />
                    <asp:Xml ID="Xml1" runat="server"></asp:Xml>
 
                </asp:Panel>
            </ContentTemplate>
        </asp:UpdatePanel>
       
        <asp:UpdateProgress ID="updProgress"
        AssociatedUpdatePanelID="UpdatePanel1"
        runat="server">
            <ProgressTemplate>           
            <img alt="progress" src="images/progress.gif"/>        
            </ProgressTemplate>
        </asp:UpdateProgress>
 
    </div>
    </form>
</body>
</html>
 
Shown above is a TextBox and Button control to accept I.P information from the user and submit it to the service. The controls have been kept inside an UpdatePanel to avoid postbacks. We have also added an UpdateProgress control to display a progress status to the user while the data is being fetched.
Note: If you are not familiar with the UpdateProgress control, read my article 3 Different Ways to Display Progress in an ASP.NET AJAX Application
You will also observe that an XML control (<asp:Xml ID="Xml1") has been added to the page. As given in the MSDN documentation, you can use the XML Web server control to write an XML document, or the results of an XSL Transformations (XSLT), into a Web page.
One drawback in using the XML control is that it has no way (not one that I know of) to accept an encoded HTML string.
Our XSLT will look similar to the following:
<?xmlversion='1.0'?>
<xsl:stylesheetxmlns:xsl="http://www.w3.org/1999/XSL/Transform"version="1.0">
 <xsl:templatematch="/">
    <HTML>
      <BODY>
        <TABLEcellspacing="3"cellpadding="8">
          <TR>
            <TDclass="heading">
              <B>Ip</B>
            </TD>
            <TDclass="heading">
              <B>Status</B>
            </TD>
            <TDclass="heading">
              <B>CountryCode</B>
            </TD>
            <TDclass="heading">
              <B>CountryName</B>
            </TD>
            <TDclass="heading">
              <B>RegionCode</B>
            </TD>
            <TDclass="heading">
              <B>RegionName</B>
            </TD>
            <TDclass="heading">
              <B>City</B>
            </TD>
            <TDclass="heading">
              <B>ZipPostalCode</B>
            </TD>
            <TDclass="heading">
              <B>Latitude</B>
            </TD>
            <TDclass="heading">
              <B>Longitude</B>
            </TD>
          </TR>
          <xsl:for-eachselect="Locations/Location">
            <TRbgcolor="#C1DAD7">
              <TDwidth="5%"valign="top">
                <xsl:value-ofselect="Ip"/>
              </TD>
              <TDwidth="5%"valign="top">
                <xsl:value-ofselect="Status"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="CountryCode"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="CountryName"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="RegionCode"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="RegionName"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="City"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="ZipPostalCode"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="Latitude"/>
              </TD>
              <TDwidth="10%"valign="top">
                <xsl:value-ofselect="Longitude"/>
              </TD>
            </TR>
          </xsl:for-each>
        </TABLE>
      </BODY>
    </HTML>
 </xsl:template>
</xsl:stylesheet>
The last step is to fetch the geographical data from the API. Add a reference to the System.Xml.Linq namespace and add the following code to the button click event
 C#
 
    protected void btnGetLoc_Click(object sender, EventArgs e)
    {
        String url = String.Empty;       
 
        if (txtIP.Text.Trim() != String.Empty)
        {
url = String.Format("http://iplocationtools.com/ip_query2.php?ip={0}", txtIP.Text.Trim());
            XDocument xDoc = XDocument.Load(url);
            if (xDoc == null | xDoc.Root == null)
            {
                throw new ApplicationException("Data is not Valid");
            }
 
            Xml1.TransformSource = "IP.xslt";
            Xml1.DocumentContent = xDoc.ToString();
        }      
    }
 VB.NET
       Protected Sub btnGetLoc_Click(ByVal sender As Object, ByVal e As  EventArgs)
            Dim url As String = String.Empty
 
            If txtIP.Text.Trim() <> String.Empty Then
url = String.Format("http://iplocationtools.com/ip_query2.php?ip={0}", txtIP.Text.Trim())
                  Dim xDoc As XDocument = XDocument.Load(url)
                  If xDoc Is Nothing Or xDoc.Root Is Nothing Then
                        Throw New ApplicationException("Data is not Valid")
                  End If
 
                  Xml1.TransformSource = "IP.xslt"
                  Xml1.DocumentContent = xDoc.ToString()
            End If
      End Sub
 
As you can observe, in order to consume the XML API, all we did was pass the url to the XDocument.Load(url)method. I hope you can realize how powerful LINQToXML is!
Once we received the XML document, we used the ‘DocumentContent’ property of the XML control to display the XML document. The XSLT was applied using the ‘TransformSource’ property.
Let us run the application. Type two I.P Addresses in the textbox as shown here and hit on the click button:
 
IpAddress_1
 The XML document is fetched and transformed using XSLT. The resultant output UI is as shown below, which in my honest (developer) opinion, looks decent!
 
IpAddress_2
 Note: You cannot do much in terms of finding geolocation information if the person is behind an anonymous proxy.
For those who do not want to parse XML, JSON is the way to go. You can check the JSON API over here http://iplocationtools.com/ip_location_api_json.php. If you are interested in consuming JSON in ASP.NET, I have covered it in one of my articles here Consume an ASP.NET WebService returning List<> with Dates using jQuery.
The entire source code of this article can be downloaded from here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Suprotim Agarwal, MCSD, MCAD, MCDBA, MCSE, is the founder of DotNetCurry, DNC Magazine for Developers, SQLServerCurry and DevCurry. He has also authored a couple of books 51 Recipes using jQuery with ASP.NET Controls and The Absolutely Awesome jQuery CookBook.

Suprotim has received the prestigious Microsoft MVP award for Sixteen consecutive years. In a professional capacity, he is the CEO of A2Z Knowledge Visuals Pvt Ltd, a digital group that offers Digital Marketing and Branding services to businesses, both in a start-up and enterprise environment.

Get in touch with him on Twitter @suprotimagarwal or at LinkedIn



Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Necqui on Sunday, May 31, 2009 4:17 AM
How do I load and store a JSON result?
XDocument xDoc = XDocument.Load(url); // <-- what is a JSON Equivalent of this?
Comment posted by Tim on Monday, June 1, 2009 3:35 AM
You can consider to download the complete commercial level database and host it in your own site.

We are using the database from http://www.ip2location.com
Comment posted by Vijaya Kadiyala on Wednesday, June 3, 2009 5:00 PM
Its really nice article.
Comment posted by Zms on Monday, July 20, 2009 2:17 PM
The webservice doesn't seem to work any longer?
Comment posted by Kyaw Aung Win on Sunday, August 16, 2009 3:26 AM
i think it can be work with that...

http://ipinfodb.com/ip_location_api.php
Comment posted by Aman Gupta on Friday, August 28, 2009 12:10 AM
The webservice doesn't seem to work any longer?
Comment posted by Muthu Vijayan on Saturday, December 19, 2009 12:26 PM
Hi Getting the users ip address from asp.net is below in the link.
http://dotnetpgm.blogspot.com/2009/09/how-to-get-ip-address-in-aspnet.html
Comment posted by tanweer on Thursday, August 12, 2010 4:21 AM
Dim ipAddress As String = something
        Dim req As WebRequest = WebRequest.Create("http://ipinfodb.com/ip_query.php?ip=" & ipAddress)
        Dim resp As WebResponse = req.GetResponse()
        Dim s As Stream = resp.GetResponseStream()
        Dim sr As StreamReader = New StreamReader(s, Encoding.ASCII)
        Dim doc As String = sr.ReadToEnd() ' get text to a string
        Dim length As Integer = doc.Length - 1
        Dim startInd As Integer = doc.IndexOf("<CountryCode>") + 13
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        Dim tagStart As Integer = doc.IndexOf("<")
        Dim code As String = doc.Remove(tagStart, length - tagStart)
        startInd = doc.IndexOf("<CountryName>") + 13
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        tagStart = doc.IndexOf("<")
        Dim Country As String = doc.Remove(tagStart, length - tagStart)
        startInd = doc.IndexOf("<RegionName>") + 12
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        tagStart = doc.IndexOf("<")
        Dim RegionName As String = doc.Remove(tagStart, length - tagStart)
        startInd = doc.IndexOf("<City>") + 6
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        tagStart = doc.IndexOf("<")
        Dim City As String = doc.Remove(tagStart, length - tagStart)
        startInd = doc.IndexOf("<ZipPostalCode>") + 15
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        tagStart = doc.IndexOf("<")
        Dim ZipCode As String = doc.Remove(tagStart, length - tagStart)
        startInd = doc.IndexOf("<Latitude>") + 10
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        tagStart = doc.IndexOf("<")
        Dim Latitude As String = doc.Remove(tagStart, length - tagStart)
        startInd = doc.IndexOf("<Longitude>") + 11
        doc = doc.Substring(startInd)
        length = doc.Length - 1
        tagStart = doc.IndexOf("<")
        Dim Longitude As String = doc.Remove(tagStart, length - tagStart)
Comment posted by saurabh Agrawal on Wednesday, May 18, 2011 10:07 AM
thanx a lot
Comment posted by Devs on Wednesday, July 20, 2011 1:26 AM
hi.
i have follow all step but i get error like this."The 'meta' start tag on line 12 does not match the end tag of 'head'. Line 13, position 3."
so plz give suggestion me.
how to solve that error.
thanks in advance...
Comment posted by sylvia peter on Friday, December 16, 2011 4:57 AM
i did all the steps.. and i run the code.. i gave the input as 74.125.45.100.. but i didn't get any information. i get the information like this ..

<Response>
  <Status>false</Status>
  <Ip>74.125.45.100</Ip>
  <CountryCode></CountryCode>
  <CountryName></CountryName>
  <RegionCode></RegionCode>
  <RegionName></RegionName>
  <City></City>
  <ZipCode></ZipCode>
  <Latitude></Latitude>
  <Longitude></Longitude>
</Response>

can anyone tell, why tis is happening..?
Comment posted by Jack Andolini on Friday, January 13, 2012 6:53 PM
Have you tried using this company?
www.IPAddressLabs.com

I have been using them for a few months, and so far I think they are very accurate, fast enough, and RELIABLE. As far as we can tell, the service has been up virtually 100% of the time, or at least we haven't detected any failures.
Comment posted by Rakesh on Friday, January 20, 2012 12:47 AM
By using this code i am getting following error.

error:  '=' is an unexpected token. The expected token is ';'. Line 36, position 63.

Please tell me how can i resolve this problem.
Comment posted by Manish Singh on Friday, February 3, 2012 12:38 AM
same error also occur with my code : '=' is an unexpected token. The expected token is ';'. Line 36, position 63.

Please help!
Comment posted by ak on Thursday, May 10, 2012 2:38 PM
i found a good solution for getting geolocation through IP
http://languagelassi.blogspot.in/2012/05/geolocation-through-ip-address.html
Comment posted by Anjnesh on Wednesday, September 19, 2012 1:17 AM
By using this code i am getting following error.

error:  '=' is an unexpected token. The expected token is ';'. Line 36, position 63.

Please tell me how can i resolve this problem.
Comment posted by abi on Friday, September 21, 2012 2:56 AM
hi am getting this error:  '=' is an unexpected token. The expected token is ';'. Line 36, position 63. pls help me how to clear this error

Comment posted by yasser zaid on Tuesday, October 2, 2012 3:34 AM
I am getting this error:  '=' is an unexpected token. The expected token is ';'. Line 36, position 63. pls help me how to clear this error
Comment posted by Chinu on Friday, November 2, 2012 6:15 AM
I'm also getting below error.
'=' is an unexpected token. The expected token is ';'. Line 36, position 63.
Comment posted by noman on Saturday, January 5, 2013 7:47 AM
I'm also getting below error.
'=' is an unexpected token. The expected token is ';'. Line 36, position 63.
Comment posted by Ashok Luhach on Friday, March 15, 2013 12:18 AM
I'm also getting below error.
'=' is an unexpected token. The expected token is ';'. Line 36, position 63.
pls help me how to clear this error i need it immediately
Comment posted by SD Dwivedi on Tuesday, October 28, 2014 11:40 AM
what is the reason of this error also occur with my code : '=' is an unexpected token. The expected token is ';'. Line 36, position 63?