Tutorial :How to get a user's client IP address in ASP.NET?


We have Request.UserHostAddress to get the IP address in ASP.NET, but this is usually the user's ISP's IP address, not exactly the user's machine IP address who for example clicked a link. How can I get the real IP Address?

For example, in a Stack Overflow user profile it is: "Last account activity: 4 hours ago from", but my machine IP address is a bit different. How does Stack Overflow get this address?

In some web systems there is an IP address check for some purposes. For example, with a certain IP address, for every 24 hours can the user just have only 5 clicks on download links? This IP address should be unique, not for an ISP that has a huge range of clients or Internet users.

Did I understand well?


As others have said you can't do what you are asking. If you describe the problem you are trying to solve maybe someone can help? E.g. are you trying to uniquely identify your users? Could you use a cookie, or the session ID perhaps instead of the IP address?

Edit The address you see on the server shouldn't be the ISP's address, as you say that would be a huge range. The address for a home user on broadband will be the address at their router, so every device inside the house will appear on the outside to be the same, but the router uses NAT to ensure that traffic is routed to each device correctly. For users accessing from an office environment the address may well be the same for all users. Sites that use IP address for ID run the risk of getting it very wrong - the examples you give are good ones and they often fail. For example my office is in the UK, the breakout point (where I "appear" to be on the internet) is in another country where our main IT facility is, so from my office my IP address appears to be not in the UK. For this reason I can't access UK only web content, such as the BBC iPlayer). At any given time there would be hundreds, or even thousands, of people at my company who appear to be accessing the web from the same IP address.

When you are writing server code you can never be sure what the IP address you see is referring to. Some users like it this way. Some people deliberately use a proxy or VPN to further confound you.

When you say your machine address is different to the IP address shown on StackOverflow, how are you finding out your machine address? If you are just looking locally using ipconfig or something like that I would expect it to be different for the reasons I outlined above. If you want to double check what the outside world thinks have a look at whatismyipaddress.com/.

This Wikipedia link on NAT will provide you some background on this.


Often you will want to know the IP address of someone visiting your website. While ASP.NET has several ways to do this one of the best ways we've seen is by using the "HTTP_X_FORWARDED_FOR" of the ServerVariables collection.

Here's why...

Sometimes your visitors are behind either a proxy server or a router and the standard Request.UserHostAddress only captures the IP address of the proxy server or router. When this is the case the user's IP address is then stored in the server variable ("HTTP_X_FORWARDED_FOR").

So what we want to do is first check "HTTP_X_FORWARDED_FOR" and if that is empty we then simply return ServerVariables("REMOTE_ADDR").

While this method is not foolproof, it can lead to better results. Below is the ASP.NET code in VB.NET, taken from James Crowley's blog post "Gotcha: HTTP_X_FORWARDED_FOR returns multiple IP addresses"


protected string GetIPAddress()  {      System.Web.HttpContext context = System.Web.HttpContext.Current;       string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];        if (!string.IsNullOrEmpty(ipAddress))      {          string[] addresses = ipAddress.Split(',');          if (addresses.Length != 0)          {              return addresses[0];          }      }        return context.Request.ServerVariables["REMOTE_ADDR"];  }  


Public Shared Function GetIPAddress() As String      Dim context As System.Web.HttpContext = System.Web.HttpContext.Current      Dim sIPAddress As String = context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")      If String.IsNullOrEmpty(sIPAddress) Then          Return context.Request.ServerVariables("REMOTE_ADDR")      Else          Dim ipArray As String() = sIPAddress.Split(New [Char]() {","c})          Return ipArray(0)      End If  End Function  


UPDATE: Thanks to Bruno Lopes. If several ip addresses could come then need to use this method:

    private string GetUserIP()      {          string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];            if (!string.IsNullOrEmpty(ipList))          {              return ipList.Split(',')[0];          }            return Request.ServerVariables["REMOTE_ADDR"];      }  


What else do you consider the user IP address? If you want the IP address of the network adapter, I'm afraid there's no possible way to do it in a Web app. If your user is behind NAT or other stuff, you can't get the IP either.

Update: While there are Web sites that use IP to limit the user (like rapidshare), they don't work correctly in NAT environments.


I think I should share my experience with you all. Well I see in some situations REMOTE_ADDR will NOT get you what you are looking for. For instance, if you have a Load Balancer behind the scene and if you are trying to get the Client's IP then you will be in trouble. I checked it with my IP masking software plus I also checked with my colleagues being in different continents. So here is my solution.

When I want to know the IP of a client, I try to pick every possible evidence so I could determine if they are unique:

Here I found another sever-var that could help you all if you want to get exact IP of the client side. so I am using : HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IP always gets you the exact IP of the client. In any case if its not giving you the value, you should then look for HTTP_X_FORWARDED_FOR as it is the second best candidate to get you the client IP and then the REMOTE_ADDR var which may or may not return you the IP but to me having all these three is what I find the best thing to monitor them.

I hope this helps some guys.


If is c# see this way, is very simple

string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ??                      Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();  


You can use:



IP addresses are part of the Network layer in the "seven-layer stack". The Network layer can do whatever it wants to do with the IP address. That's what happens with a proxy server, NAT, relay, or whatever.

The Application layer should not depend on the IP address in any way. In particular, an IP Address is not meant to be an identifier of anything other than the idenfitier of one end of a network connection. As soon as a connection is closed, you should expect the IP address (of the same user) to change.


If you are using CloudFlare, you can try this Extension Method:

public static class IPhelper  {      public static string GetIPAddress(this HttpRequest Request)      {          if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();            if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();            return Request.UserHostAddress;      }  }  


string IPAddress = Request.GetIPAddress();  


string IP = HttpContext.Current.Request.Params["HTTP_CLIENT_IP"] ?? HttpContext.Current.Request.UserHostAddress;  


What you can do is store the router IP of your user and also the forwarded IP and try to make it reliable using both the IPs [External Public and Internal Private]. But again after some days client may be assigned new internal IP from router but it will be more reliable.


use in ashx file

public string getIP(HttpContext c)  {      string ips = c.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];      if (!string.IsNullOrEmpty(ips))      {          return ips.Split(',')[0];      }      return c.Request.ServerVariables["REMOTE_ADDR"];  }  


All of the responses so far take into account the non-standardized, but very common, X-Forwarded-For header. There is a standardized Forwarded header which is a little more difficult to parse out. Some examples are as follows:

Forwarded: for="_gazonk"  Forwarded: For="[2001:db8:cafe::17]:4711"  Forwarded: for=;proto=http;by=  Forwarded: for=, for=  

I have written a class that takes both of these headers into account when determining a client's IP address.

using System;  using System.Web;    namespace Util  {      public static class IP      {          public static string GetIPAddress()          {              return GetIPAddress(new HttpRequestWrapper(HttpContext.Current.Request));          }            internal static string GetIPAddress(HttpRequestBase request)          {              // handle standardized 'Forwarded' header              string forwarded = request.Headers["Forwarded"];              if (!String.IsNullOrEmpty(forwarded))              {                  foreach (string segment in forwarded.Split(',')[0].Split(';'))                  {                      string[] pair = segment.Trim().Split('=');                      if (pair.Length == 2 && pair[0].Equals("for", StringComparison.OrdinalIgnoreCase))                      {                          string ip = pair[1].Trim('"');                            // IPv6 addresses are always enclosed in square brackets                          int left = ip.IndexOf('['), right = ip.IndexOf(']');                          if (left == 0 && right > 0)                          {                              return ip.Substring(1, right - 1);                          }                            // strip port of IPv4 addresses                          int colon = ip.IndexOf(':');                          if (colon != -1)                          {                              return ip.Substring(0, colon);                          }                            // this will return IPv4, "unknown", and obfuscated addresses                          return ip;                      }                  }              }                // handle non-standardized 'X-Forwarded-For' header              string xForwardedFor = request.Headers["X-Forwarded-For"];              if (!String.IsNullOrEmpty(xForwardedFor))              {                  return xForwardedFor.Split(',')[0];              }                return request.UserHostAddress;          }      }  }  

Below are some unit tests that I used to validate my solution:

using System.Collections.Specialized;  using System.Web;  using Microsoft.VisualStudio.TestTools.UnitTesting;    namespace UtilTests  {      [TestClass]      public class IPTests      {          [TestMethod]          public void TestForwardedObfuscated()          {              var request = new HttpRequestMock("for=\"_gazonk\"");              Assert.AreEqual("_gazonk", Util.IP.GetIPAddress(request));          }            [TestMethod]          public void TestForwardedIPv6()          {              var request = new HttpRequestMock("For=\"[2001:db8:cafe::17]:4711\"");              Assert.AreEqual("2001:db8:cafe::17", Util.IP.GetIPAddress(request));          }            [TestMethod]          public void TestForwardedIPv4()          {              var request = new HttpRequestMock("for=;proto=http;by=");              Assert.AreEqual("", Util.IP.GetIPAddress(request));          }            [TestMethod]          public void TestForwardedIPv4WithPort()          {              var request = new HttpRequestMock("for=;proto=http;by=");              Assert.AreEqual("", Util.IP.GetIPAddress(request));          }            [TestMethod]          public void TestForwardedMultiple()          {              var request = new HttpRequestMock("for=, for=");              Assert.AreEqual("", Util.IP.GetIPAddress(request));          }      }        public class HttpRequestMock : HttpRequestBase      {          private NameValueCollection headers = new NameValueCollection();            public HttpRequestMock(string forwarded)          {              headers["Forwarded"] = forwarded;          }            public override NameValueCollection Headers          {              get { return this.headers; }          }      }  }  


Combining the answers from @Tony and @mangokun, I have created the following extension method:

public static class RequestExtensions  {      public static string GetIPAddress(this HttpRequest Request)      {          if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();            if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)          {              string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];                if (!string.IsNullOrEmpty(ipAddress))              {                  string[] addresses = ipAddress.Split(',');                  if (addresses.Length != 0)                  {                      return addresses[0];                  }              }          }            return Request.UserHostAddress;      }  }  


use this




using System.Net;    public static string GetIpAddress()  // Get IP Address  {      string ip = "";           IPHostEntry ipEntry = Dns.GetHostEntry(GetCompCode());      IPAddress[] addr = ipEntry.AddressList;      ip = addr[2].ToString();      return ip;  }  public static string GetCompCode()  // Get Computer Name  {         string strHostName = "";      strHostName = Dns.GetHostName();      return strHostName;  }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Next Post »