简体   繁体   中英

Asp Net Web API 2.1 get client IP address

Hello I need get client IP that request some method in web api, I have tried to use this code from here but it always returns server local IP, how to get in correct way ?

HttpContext.Current.Request.UserHostAddress;

from other questions:

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;
        }
    }

Following link might help you. Here's code from the following link.

reference : 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;
                }
           }
     }
}

Another way of doing this is below.

reference: how-to-access-the-client-s-ip-address

For web hosted version

string clientAddress = HttpContext.Current.Request.UserHostAddress;

For self hosted

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

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

尝试使用

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

If you're self-hosting with Asp.Net 2.1 using the OWIN Self-host NuGet package you can use the following code:

 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;
    }

I think this is the most clear solution, using an extension method:

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;
    }
}

So just use it like:

var ipAddress = request.GetClientIpAddress();

We use this in our projects.

Source/Reference: Retrieving the client's IP address in ASP.NET Web API

Replying to this 4 year old post, because this seems overcomplicated to me, at least if you're hosting on IIS.

Here's how I solved it:

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);
        ...

Unlike OP, this gives me the client IP and client hostname, not the server. Perhaps they've fixed the bug since then?

It's better to cast it to HttpContextBase , this way you can mock and test it more easily

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;
}

My solution is similar to user1587439's answer, but works directly on the controller's instance (instead of accessing HttpContext.Current).

In the 'Watch' window, I saw that this.RequestContext.WebRequest contains the 'UserHostAddress' property, but since it relies on the WebHostHttpRequestContext type (which is internal to the 'System.Web.Http' assembly) - I wasn't able to access it directly, so I used reflection to directly access it:

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

I'm not saying it's the best solution. using reflection may cause issues in the future in case of framework upgrade (due to name changes), but for my needs it's perfect

string userRequest = System.Web.HttpContext.Current.Request.UserHostAddress;

This works on me.

System.Web.HttpContext.Current.Request.UserHostName; this one return me the same return I get from the UserHostAddress .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM