You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用ASP.NET Core通过IP地址计算站点用户间的地理距离

实现步骤总览

总共分4个核心环节:获取用户真实IP -> IP解析为经纬度坐标 -> 封装距离计算方法 -> 业务逻辑集成

1. 在ASP.NET Core 5中获取用户真实IP

首先要注意如果站点用了反向代理(比如Nginx、Cloudflare),必须先配置转发头,不然拿到的是代理服务器的IP。

配置转发头

修改Startup.cs文件:

// ConfigureServices方法中添加
services.Configure<ForwardedHeadersOptions>(options =>
{
    options.ForwardedHeaders = Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedFor | Microsoft.AspNetCore.HttpOverrides.ForwardedHeaders.XForwardedProto;
    // 生产环境建议指定信任的代理IP,测试环境可以清空KnownProxies允许所有
    options.KnownProxies.Clear();
});

// Configure方法中,放在所有中间件的最开头添加
app.UseForwardedHeaders();

控制器中获取IP代码

var userIp = Request.HttpContext.Connection.RemoteIpAddress?.ToString();
// 处理IPv6映射的IPv4格式,提取有效IPv4地址
if (userIp != null && userIp.StartsWith("::ffff:"))
{
    userIp = userIp.Substring(7);
}

2. IP地址转经纬度坐标

推荐用离线IP地理库实现,无接口请求限制、性能更高,常用开源库为GeoLite2:

  1. 安装NuGet包:MaxMind.GeoIP2
  2. 下载离线IP库文件GeoLite2-City.mmdb,放入站点App_Data目录
  3. 封装IP解析方法:
using MaxMind.GeoIP2;

public (double Latitude, double Longitude)? GetGeoFromIp(string ip)
{
    try
    {
        using var reader = new DatabaseReader("App_Data/GeoLite2-City.mmdb");
        var city = reader.City(ip);
        return (city.Location.Latitude.Value, city.Location.Longitude.Value);
    }
    catch
    {
        // 内网IP、保留IP等解析失败场景返回null
        return null;
    }
}

解析得到的经纬度可以存入用户表扩展字段,用户访问/登录时更新即可,无需每次请求重复解析。

3. 计算两个经纬度点之间的地理距离

用Haversine公式计算地球球面两点距离,精度满足普通业务场景,以下示例返回单位为公里:

/// <summary>
/// 计算两个经纬度之间的距离,返回单位:公里
/// </summary>
public double CalculateDistance(double lat1, double lon1, double lat2, double lon2)
{
    // 地球平均半径,单位:公里
    const double earthRadius = 6371;
    // 角度转弧度
    var dLat = ToRadians(lat2 - lat1);
    var dLon = ToRadians(lon2 - lon1);
    var a = 
        Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
        Math.Cos(ToRadians(lat1)) * Math.Cos(ToRadians(lat2)) *
        Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
    var c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
    return earthRadius * c;
}

private double ToRadians(double degrees)
{
    return degrees * Math.PI / 180;
}

4. 业务逻辑集成示例

以查询当前用户和平台其他用户的距离为例:

  1. 用户访问站点时,获取IP解析为经纬度,更新到对应用户数据
  2. 从用户表拉取所有存在有效经纬度的其他用户
  3. 遍历调用CalculateDistance方法,计算当前用户和每个目标用户的距离
  4. 按需做排序、筛选(比如仅返回5公里以内的用户)等业务处理

注意事项

  • 内网IP(比如127.0.0.1、192.168开头的)无法解析到公网地理位置,本地开发时可以自行写死测试经纬度
  • GeoLite2库每月更新一次,定期更新mmdb文件可以提升IP解析精度
  • 如果需要更高精度的国内IP解析,可以替换为国内的离线IP库,整体逻辑保持不变,仅更换解析类库即可

内容的提问来源于stack exchange,提问作者Pouriya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:24:04