首页 文章

Asp Net Web API 2.1获取客户端IP地址

提问于
浏览
92

您好我需要获取请求web api中的某些方法的客户端IP,我已经尝试使用here中的此代码,但它总是返回服务器本地IP,如何以正确的方式获取?

HttpContext.Current.Request.UserHostAddress;

来自其他问题:

public static class HttpRequestMessageExtensions
    {
        private const string HttpContext = "MS_HttpContext";
        private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";

        public static string GetClientIpAddress(this HttpRequestMessage request)
        {
            if (request.Properties.ContainsKey(HttpContext))
            {
                dynamic ctx = request.Properties[HttpContext];
                if (ctx != null)
                {
                    return ctx.Request.UserHostAddress;
                }
            }

            if (request.Properties.ContainsKey(RemoteEndpointMessage))
            {
                dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
                if (remoteEndpoint != null)
                {
                    return remoteEndpoint.Address;
                }
            }

            return null;
        }
    }

8 回答

  • 2

    以下链接可能对您有帮助 . 以下是来自以下链接的代码 .

    参考:getting-the-client-ip-via-asp-net-web-api

    using System.Net.Http;
    using System.ServiceModel.Channels;
    using System.Web;
    using System.Web.Http;
    
    
    namespace Trikks.Controllers.Api
    {
        public class IpController : ApiController
        {
              public string GetIp()
              {
                    return GetClientIp();
              }
    
              private string GetClientIp(HttpRequestMessage request = null)
              {
                    request = request ?? Request;
    
                    if (request.Properties.ContainsKey("MS_HttpContext"))
                    {
                          return   ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
                    }
                    else if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
                    {
                         RemoteEndpointMessageProperty prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
                         return prop.Address;
                    }
                    else if (HttpContext.Current != null)
                    {
                        return HttpContext.Current.Request.UserHostAddress;
                    }
                    else
                    {
                          return null;
                    }
               }
         }
    }
    

    另一种方法是在下面 .

    参考:how-to-access-the-client-s-ip-address

    对于Web托管版本

    string clientAddress = HttpContext.Current.Request.UserHostAddress;
    

    为自我托管

    object property;
            Request.Properties.TryGetValue(typeof(RemoteEndpointMessageProperty).FullName, out property);
            RemoteEndpointMessageProperty remoteProperty = property as RemoteEndpointMessageProperty;
    
  • 2

    使用Web API 2.2: Request.GetOwinContext().Request.RemoteIpAddress

  • 15

    尝试使用Ip

    ip = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "";
    
  • 67

    如果您使用OWIN Self-host NuGet包进行Asp.Net 2.1自托管,则可以使用以下代码:

    private string getClientIp(HttpRequestMessage request = null)
        {
            if (request == null)
            {
                return null;
            }
    
            if (request.Properties.ContainsKey("MS_OwinContext"))
            {
                return ((OwinContext) request.Properties["MS_OwinContext"]).Request.RemoteIpAddress;
            }
            return null;
        }
    
  • 6

    最好将其强制转换为 HttpContextBase ,这样您就可以更轻松地模拟和测试它

    public string GetUserIp(HttpRequestMessage request)
    {
        if (request.Properties.ContainsKey("MS_HttpContext"))
        {
            var ctx = request.Properties["MS_HttpContext"] as HttpContextBase;
            if (ctx != null)
            {
                return ctx.Request.UserHostAddress;
            }
        }
    
        return null;
    }
    
  • 96

    我认为这是最明确的解决方案,使用扩展方法:

    public static class HttpRequestMessageExtensions
    {
        private const string HttpContext = "MS_HttpContext";
        private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
    
        public static string GetClientIpAddress(this HttpRequestMessage request)
        {
            if (request.Properties.ContainsKey(HttpContext))
            {
                dynamic ctx = request.Properties[HttpContext];
                if (ctx != null)
                {
                    return ctx.Request.UserHostAddress;
                }
            }
    
            if (request.Properties.ContainsKey(RemoteEndpointMessage))
            {
                dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
                if (remoteEndpoint != null)
                {
                    return remoteEndpoint.Address;
                }
            }
    
            return null;
        }
    }
    

    所以就像使用它一样:

    var ipAddress = request.GetClientIpAddress();
    

    我们在项目中使用它 .

    来源/参考:Retrieving the client’s IP address in ASP.NET Web API

  • 4

    我的解决方案类似于user1587439的答案,但直接在控制器的实例上工作(而不是访问HttpContext.Current) .

    在'Watch'窗口中,我看到this.RequestContext.WebRequest包含'UserHostAddress'属性,但由于它依赖于WebHostHttpRequestContext类型(它是'System.Web.Http'程序集内部) - 我不是能够直接访问它,所以我用反射直接访问它:

    string hostAddress = ((System.Web.HttpRequestWrapper)this.RequestContext.GetType().Assembly.GetType("System.Web.Http.WebHost.WebHostHttpRequestContext").GetProperty("WebRequest").GetMethod.Invoke(this.RequestContext, null)).UserHostAddress;

    我不是说这是最好的解决方案 . 在框架升级的情况下(由于名称更改),使用反射可能会在将来导致问题,但是对于我的需求,它是完美的

  • 5

    回复这篇4年的帖子,因为这对我来说似乎过于复杂,至少如果你在IIS上主持,这篇文章对于“web api控制器获取IP地址”的DuckDuckGo(可能是NSAoogle)非常高 .

    这是我解决它的方式:

    using System;
    using System.Net;
    using System.Web;
    using System.Web.Http;
    ...
    [HttpPost]
    [Route("ContactForm")]
    public IHttpActionResult PostContactForm([FromBody] ContactForm contactForm)
        {
            var hostname = HttpContext.Current.Request.UserHostAddress;
            IPAddress ipAddress = IPAddress.Parse(hostname);
            IPHostEntry ipHostEntry = Dns.GetHostEntry(ipAddress);
            ...
    

    与OP不同,这为我提供了客户端IP和客户端主机名,而不是服务器 . 也许从那时起他们就修复了这个bug?

相关问题