Asp Net Web API 2.1 รับที่อยู่ IP ของไคลเอ็นต์


112

สวัสดีฉันต้องการรับ IP ไคลเอนต์ที่ขอวิธีการบางอย่างใน web api ฉันได้พยายามใช้รหัสนี้จากที่นี่แต่จะส่งคืน 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;
        }
    }

วิธีการขยายนี้ใช้ได้ดีสำหรับฉัน (ฉันไม่ได้ใช้ OWIN หรืออะไรที่ผิดปกติ)
Nate Barbettini

ยินดีที่ได้รับทราบแหล่งที่มา แก้ไข
Stefano Mtangoo

คำตอบ:


124

ลิงก์ต่อไปนี้อาจช่วยคุณได้ นี่คือรหัสจากลิงค์ต่อไปนี้

การอ้างอิง: 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;
                }
           }
     }
}

อีกวิธีในการทำเช่นนี้อยู่ด้านล่าง

การอ้างอิง: วิธีการเข้าถึงที่อยู่ไคลเอ็นต์ -s-ip-address

สำหรับเวอร์ชันที่โฮสต์บนเว็บ

string clientAddress = HttpContext.Current.Request.UserHostAddress;

สำหรับโฮสต์ด้วยตนเอง

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


16

ลองรับ Ip โดยใช้

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

1
@DenisBabarykin ฉันคิดว่ามันควร .. มันคืนค่าที่อยู่ IP ในตัวแปรเซิร์ฟเวอร์ REMOTE_ADDR
user1587439

9

หากคุณโฮสต์ด้วยตนเองด้วย Asp.Net 2.1 โดยใช้แพ็คเกจ NuGet โฮสต์ด้วยตนเองของ OWIN คุณสามารถใช้รหัสต่อไปนี้:

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

7

ตอบโพสต์นี้เมื่อ 4 ปีที่แล้วเพราะดูเหมือนว่าจะซับซ้อนเกินไปสำหรับฉันอย่างน้อยถ้าคุณโฮสต์บน IIS และโพสต์นี้สูงมากใน DuckDuckGo (และอาจเป็น NSAoogle) สำหรับ "web api controller get IP address"

นี่คือวิธีที่ฉันแก้ไข:

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 ไคลเอ็นต์และชื่อโฮสต์ไคลเอนต์ไม่ใช่เซิร์ฟเวอร์ บางทีพวกเขาได้แก้ไขข้อบกพร่องตั้งแต่นั้นมา?


ชอบที่จะเห็นคำตอบสำหรับการใช้ DotNetCore web API ฉันไม่อยากจะเชื่อเลยว่ามันเป็นเรื่องยากที่จะทำอะไรที่เป็นพื้นฐาน
MC9000

5

จะดีกว่าที่จะส่งไปให้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;
}

1
ฉัน googled ไปรอบ ๆ และคนอื่น ๆ ดูเหมือนจะเห็นด้วยกับสิ่งนี้ (ส่งไปที่ HttpContextBase แทน HttpContextWrapper เพราะ HttpContextBase นั้นง่ายกว่าที่จะเยาะเย้ย)
Dave Clausen

4

ฉันคิดว่านี่เป็นวิธีแก้ปัญหาที่ชัดเจนที่สุดโดยใช้วิธีการขยาย:

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

เราใช้สิ่งนี้ในโครงการของเรา

แหล่งที่มา / ข้อมูลอ้างอิง: การดึงที่อยู่ IP ของไคลเอนต์ใน ASP.NET Web API


2

วิธีแก้ปัญหาของฉันคล้ายกับคำตอบของ user1587439 แต่ทำงานโดยตรงบนอินสแตนซ์ของคอนโทรลเลอร์ (แทนที่จะเข้าถึง HttpContext.Current)

ในหน้าต่าง 'Watch' ฉันเห็นว่าสิ่งนี้ 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;

ฉันไม่ได้บอกว่ามันเป็นทางออกที่ดีที่สุด การใช้การสะท้อนอาจทำให้เกิดปัญหาในอนาคตในกรณีของการอัปเกรดกรอบ (เนื่องจากการเปลี่ยนแปลงชื่อ) แต่สำหรับความต้องการของฉันมันสมบูรณ์แบบ


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

สิ่งนี้ใช้ได้กับฉัน

System.Web.HttpContext.Current.Request.UserHostName;อันนี้ส่งคืนฉันเหมือนเดิมที่ฉันได้รับจากUserHostAddress.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.