通过IP地址获取用户位置


77

我有一个用C#编写的ASP.NET网站。

在此站点上,我需要根据用户的位置自动显示起始页。

可以根据用户的IP地址获取用户所在城市的名称吗?


2
免费Rest Api检查freegeoip.netgeoplugin.net,或检查帖子,希望对某人有所帮助。
shaijut

Answers:


45

您需要一个基于IP地址的反向地理编码API ...类似于ipdata.co中的API 。我敢肯定有很多选择。

但是,您可能希望允许用户覆盖它。例如,它们可能位于公司VPN上,这会使IP地址看起来像在其他国家一样。


2
双向飞碟!你怎么总是第一?:)
B先生

2
@乔纳森:更新。
乔恩·斯基特

2
ipregistry.co是另一个非常快速,准确的地理位置和威胁数据API (免责声明:我运行该服务)。
洛朗

26

使用http://ipinfo.io,如果每天发出1000个以上的请求,则需要付费。

下面的代码需要Json.NET软件包。

public static string GetUserCountryByIp(string ip)
{
    IpInfo ipInfo = new IpInfo();
    try
    {
        string info = new WebClient().DownloadString("http://ipinfo.io/" + ip);
        ipInfo = JsonConvert.DeserializeObject<IpInfo>(info);
        RegionInfo myRI1 = new RegionInfo(ipInfo.Country);
        ipInfo.Country = myRI1.EnglishName;
    }
    catch (Exception)
    {
        ipInfo.Country = null;
    }
    
    return ipInfo.Country;
}

IpInfo我使用的班级:

public class IpInfo
{
    [JsonProperty("ip")]
    public string Ip { get; set; }

    [JsonProperty("hostname")]
    public string Hostname { get; set; }

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

    [JsonProperty("region")]
    public string Region { get; set; }

    [JsonProperty("country")]
    public string Country { get; set; }

    [JsonProperty("loc")]
    public string Loc { get; set; }

    [JsonProperty("org")]
    public string Org { get; set; }

    [JsonProperty("postal")]
    public string Postal { get; set; }
}

17

以下代码对我有用。

更新:

当我调用一个免费的API请求(基于json的)IpStack时

    public static string CityStateCountByIp(string IP)
    {
      //var url = "http://freegeoip.net/json/" + IP;
      //var url = "http://freegeoip.net/json/" + IP;
        string url = "http://api.ipstack.com/" + IP + "?access_key=[KEY]";
        var request = System.Net.WebRequest.Create(url);
        
         using (WebResponse wrs = request.GetResponse())
         using (Stream stream = wrs.GetResponseStream())
         using (StreamReader reader = new StreamReader(stream))
         {
          string json = reader.ReadToEnd();
          var obj = JObject.Parse(json);
            string City = (string)obj["city"];
            string Country = (string)obj["region_name"];                    
            string CountryCode = (string)obj["country_code"];
        
           return (CountryCode + " - " + Country +"," + City);
           }

  return "";

}

编辑: 首先,它是http://freegeoip.net/,现在是https://ipstack.com/(也许现在是一项付费服务-每月最多可请求10,000个)


1
我不知道为什么这不是答案。干得好
BoundForGlory

1
这也支持更换jsonxml的地址,以获得XML返回结构。
DonBoitnott

您应该在最后添加API密钥。正确?
Michael Haephrati

IPStack非常不准确
user1034912 '19

1
它仍然没有几个免费游戏:)
Gaurav Kaushik

12

IPInfoDB有一个API,您可以调用该API以便根据IP地址查找位置。

对于“ City Precision”,您可以这样称呼(您需要注册以获得免费的API密钥):

 http://api.ipinfodb.com/v2/ip_query.php?key=<your_api_key>&ip=74.125.45.100&timezone=false

这是VB和C#中的示例,展示了如何调用API。


7

我尝试使用http://ipinfo.io,并且此JSON API可以完美运行。首先,您需要添加以下提到的名称空间:

using System.Linq;
using System.Web; 
using System.Web.UI.WebControls;
using System.Net;
using System.IO;
using System.Xml;
using System.Collections.Specialized;

对于本地主机,它将给出虚拟数据AU。您可以尝试对IP进行硬编码并获得结果:

namespace WebApplication4
{
    public partial class WebForm1 : System.Web.UI.Page
    {

        protected void Page_Load(object sender, EventArgs e)
         {

          string VisitorsIPAddr = string.Empty;
          //Users IP Address.                
          if (HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
          {
              //To get the IP address of the machine and not the proxy
              VisitorsIPAddr =   HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();
          }
          else if (HttpContext.Current.Request.UserHostAddress.Length != 0)
          {
              VisitorsIPAddr = HttpContext.Current.Request.UserHostAddress;`enter code here`
          }

          string res = "http://ipinfo.io/" + VisitorsIPAddr + "/city";
          string ipResponse = IPRequestHelper(res);

        }

        public string IPRequestHelper(string url)
        {

            string checkURL = url;
            HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
            HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
            StreamReader responseStream = new StreamReader(objResponse.GetResponseStream());
            string responseRead = responseStream.ReadToEnd();
            responseRead = responseRead.Replace("\n", String.Empty);
            responseStream.Close();
            responseStream.Dispose();
            return responseRead;
        }


    }
}

3
您能添加几行来解释您的解决方案吗?谢谢。
m4rtin 2014年

你能解释一下吗?
wannabeLearner

7

我能够使用客户端IP地址和freegeoip.net API在ASP.NET MVC中实现此目标。freegeoip.net是免费的,不需要任何许可。

下面是我使用的示例代码。

String UserIP = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (string.IsNullOrEmpty(UserIP))
{
    UserIP = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
}
string url = "http://freegeoip.net/json/" + UserIP.ToString();
WebClient client = new WebClient();
string jsonstring = client.DownloadString(url);
dynamic dynObj = JsonConvert.DeserializeObject(jsonstring);
System.Web.HttpContext.Current.Session["UserCountryCode"] = dynObj.country_code;

您可以阅读这篇文章以获取更多详细信息。希望它会有所帮助!


1
强烈建议不要使用仅链接的答案,因为将来链接可能会失效。建议您使用引用来源中的引号来编辑答案。
Anirudh Sharma 2015年

每天免费提供15К请求
aleha '17

5

使用以下网站的请求

http://ip-api.com/

以下是用于返回国家和地区代码的C#代码

public  string GetCountryByIP(string ipAddress)
    {
        string strReturnVal;
        string ipResponse = IPRequestHelper("http://ip-api.com/xml/" + ipAddress);

        //return ipResponse;
        XmlDocument ipInfoXML = new XmlDocument();
        ipInfoXML.LoadXml(ipResponse);
        XmlNodeList responseXML = ipInfoXML.GetElementsByTagName("query");

        NameValueCollection dataXML = new NameValueCollection();

        dataXML.Add(responseXML.Item(0).ChildNodes[2].InnerText, responseXML.Item(0).ChildNodes[2].Value);

        strReturnVal = responseXML.Item(0).ChildNodes[1].InnerText.ToString(); // Contry
        strReturnVal += "(" + 

responseXML.Item(0).ChildNodes[2].InnerText.ToString() + ")";  // Contry Code 
 return strReturnVal;
}

以下是用于请求url的Helper。

public string IPRequestHelper(string url) {

      HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
      HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();

      StreamReader responseStream = new StreamReader(objResponse.GetResponseStream());
      string responseRead = responseStream.ReadToEnd();

      responseStream.Close();
      responseStream.Dispose();

  return responseRead;
}

看来我们必须为商业用途付费。
shaijut

5

您需要的被称为“ geo-IP数据库”。它们中的大多数要花一些钱(虽然不太贵),尤其是精确的钱。MaxMind的数据库是使用最广泛的数据库之一。他们有一个称为GeoLity City的相当不错的IP到城市数据库免费版本-它有很多限制,但是如果您能解决这个问题,那将是您最好的选择,除非您有很多钱可以订阅更准确的产品。

而且,是的,它们确实具有C#API来查询可用的geo-IP数据库


这很容易知道,尤其是C#的GEO-IP选项
Martin Sansone-MiOEE 2014年

MaxMind更改了其网站结构,我已修复了链接。谢谢@Dementic。
GreyCat 2015年


4

回国

static public string GetCountry()
{
    return new WebClient().DownloadString("http://api.hostip.info/country.php");
}

用法:

Console.WriteLine(GetCountry()); // will return short code for your country

返回信息

static public string GetInfo()
{
    return new WebClient().DownloadString("http://api.hostip.info/get_json.php");
}

用法:

Console.WriteLine(GetInfo()); 
// Example:
// {
//    "country_name":"COUNTRY NAME",
//    "country_code":"COUNTRY CODE",
//    "city":"City",
//    "ip":"XX.XXX.XX.XXX"
// }

8
如果运行此命令,它将返回运行Web应用程序的服务器的国家(和此代码),而不是请求网页的客户端的国家。因此,这不是请求的用户位置。(尽管是一种非常不错的编程风格)
棘手的内容,2015年

4
目前坏掉了
HellBaby

2

这是适合您的好样本:

public class IpProperties
    {
        public string Status { get; set; }
        public string Country { get; set; }
        public string CountryCode { get; set; }
        public string Region { get; set; }
        public string RegionName { get; set; }
        public string City { get; set; }
        public string Zip { get; set; }
        public string Lat { get; set; }
        public string Lon { get; set; }
        public string TimeZone { get; set; }
        public string ISP { get; set; }
        public string ORG { get; set; }
        public string AS { get; set; }
        public string Query { get; set; }
    }
 public string IPRequestHelper(string url)
    {
        HttpWebRequest objRequest = (HttpWebRequest)WebRequest.Create(url);
        HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();

        StreamReader responseStream = new StreamReader(objResponse.GetResponseStream());
        string responseRead = responseStream.ReadToEnd();

        responseStream.Close();
        responseStream.Dispose();

        return responseRead;
    }

    public IpProperties GetCountryByIP(string ipAddress)
    {
        string ipResponse = IPRequestHelper("http://ip-api.com/xml/" + ipAddress);
        using (TextReader sr = new StringReader(ipResponse))
        {
            using (System.Data.DataSet dataBase = new System.Data.DataSet())
            {
                IpProperties ipProperties = new IpProperties();
                dataBase.ReadXml(sr);
                ipProperties.Status = dataBase.Tables[0].Rows[0][0].ToString();
                ipProperties.Country = dataBase.Tables[0].Rows[0][1].ToString();
                ipProperties.CountryCode = dataBase.Tables[0].Rows[0][2].ToString();
                ipProperties.Region = dataBase.Tables[0].Rows[0][3].ToString();
                ipProperties.RegionName = dataBase.Tables[0].Rows[0][4].ToString();
                ipProperties.City = dataBase.Tables[0].Rows[0][5].ToString();
                ipProperties.Zip = dataBase.Tables[0].Rows[0][6].ToString();
                ipProperties.Lat = dataBase.Tables[0].Rows[0][7].ToString();
                ipProperties.Lon = dataBase.Tables[0].Rows[0][8].ToString();
                ipProperties.TimeZone = dataBase.Tables[0].Rows[0][9].ToString();
                ipProperties.ISP = dataBase.Tables[0].Rows[0][10].ToString();
                ipProperties.ORG = dataBase.Tables[0].Rows[0][11].ToString();
                ipProperties.AS = dataBase.Tables[0].Rows[0][12].ToString();
                ipProperties.Query = dataBase.Tables[0].Rows[0][13].ToString();

                return ipProperties;
            }
        }
    }

并测试:

var ipResponse = GetCountryByIP("your ip address or domain name :)");

1

使用API​​的替代方法是使用HTML 5位置导航器向浏览器查询有关用户位置的信息。我一直在寻找一种与主题问题类似的方法,但是我发现HTML 5 Navigator对于我的情况更好,更便宜。请考虑您的scinario可能有所不同。要使用Html5获得用户位置非常简单:

function getLocation()
{
    if (navigator.geolocation)
    {
        navigator.geolocation.getCurrentPosition(showPosition);
    }
    else
    {
        console.log("Geolocation is not supported by this browser.");
     }
}

function showPosition(position)
{
      console.log("Latitude: " + position.coords.latitude + 
  "<br>Longitude: " + position.coords.longitude); 
}

W3Schools地理位置教程自行尝试


0
    public static string GetLocationIPAPI(string ipaddress)
    {
        try
        {
            IPDataIPAPI ipInfo = new IPDataIPAPI();
            string strResponse = new WebClient().DownloadString("http://ip-api.com/json/" + ipaddress);
            if (strResponse == null || strResponse == "") return "";
            ipInfo = JsonConvert.DeserializeObject<IPDataIPAPI>(strResponse);
            if (ipInfo == null || ipInfo.status.ToLower().Trim() == "fail") return "";
            else return ipInfo.city + "; " + ipInfo.regionName + "; " + ipInfo.country + "; " + ipInfo.countryCode;
        }
        catch (Exception)
        {
            return "";
        }
    }

public class IPDataIPINFO
{
    public string ip { get; set; }
    public string city { get; set; }
    public string region { get; set; }
    public string country { get; set; }
    public string loc { get; set; }
    public string postal { get; set; }
    public int org { get; set; }

}

=========================

    public static string GetLocationIPINFO(string ipaddress)
    {            
        try
        {
            IPDataIPINFO ipInfo = new IPDataIPINFO();
            string strResponse = new WebClient().DownloadString("http://ipinfo.io/" + ipaddress);
            if (strResponse == null || strResponse == "") return "";
            ipInfo = JsonConvert.DeserializeObject<IPDataIPINFO>(strResponse);
            if (ipInfo == null || ipInfo.ip == null || ipInfo.ip == "") return "";
            else return ipInfo.city + "; " + ipInfo.region + "; " + ipInfo.country + "; " + ipInfo.postal;
        }
        catch (Exception)
        {
            return "";
        }
    }

public class IPDataIPAPI
{
    public string status { get; set; }
    public string country { get; set; }
    public string countryCode { get; set; }
    public string region { get; set; }
    public string regionName { get; set; }
    public string city { get; set; }
    public string zip { get; set; }
    public string lat { get; set; }
    public string lon { get; set; }
    public string timezone { get; set; }
    public string isp { get; set; }
    public string org { get; set; }
    public string @as { get; set; }
    public string query { get; set; }
}

=============================

    private static string GetLocationIPSTACK(string ipaddress)
    {
        try
        {
            IPDataIPSTACK ipInfo = new IPDataIPSTACK();
            string strResponse = new WebClient().DownloadString("http://api.ipstack.com/" + ipaddress + "?access_key=XX384X1XX028XX1X66XXX4X04XXXX98X");
            if (strResponse == null || strResponse == "") return "";
            ipInfo = JsonConvert.DeserializeObject<IPDataIPSTACK>(strResponse);
            if (ipInfo == null || ipInfo.ip == null || ipInfo.ip == "") return "";
            else return ipInfo.city + "; " + ipInfo.region_name + "; " + ipInfo.country_name + "; " + ipInfo.zip;
        }
        catch (Exception)
        {
            return "";
        }
    }

public class IPDataIPSTACK
{
    public string ip { get; set; }
    public int city { get; set; }
    public string region_code { get; set; }
    public string region_name { get; set; }
    public string country_code { get; set; }
    public string country_name { get; set; }
    public string zip { get; set; }


}

请添加对此代码的作用及其用途的说明。[点评]
Artemis

-1

您可以

using System.Net;
using System.IO;
using Newtonsoft.Json.Linq;
public ActionResult geoPlugin()
    {

        var url = "http://freegeoip.net/json/";
        var request = System.Net.WebRequest.Create(url);

        using (WebResponse wrs = request.GetResponse())
        using (Stream stream = wrs.GetResponseStream())
        using (StreamReader reader = new StreamReader(stream))
        {
            string json = reader.ReadToEnd();
            var obj = JObject.Parse(json);
            var City = (string)obj["city"];
            // - For Country = (string)obj["region_name"];                    
            //- For  CountryCode = (string)obj["country_code"];
            Session["CurrentRegionName"]= (string)obj["country_name"];
            Session["CurrentRegion"] = (string)obj["country_code"];
        }
        return RedirectToAction("Index");
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.