Obtener la dirección IP del host remoto

En ASP.NET hay una clase System.Web.HttpRequest , que contiene la propiedad ServerVariables que puede proporcionarnos la dirección IP del valor de propiedad REMOTE_ADDR .

Sin embargo, no pude encontrar una forma similar de obtener la dirección IP del host remoto desde ASP.NET Web API.

¿Cómo puedo obtener la dirección IP del host remoto que realiza la solicitud?

Es posible hacer eso, pero no es muy reconocible: debe usar el bolso de propiedad de la solicitud entrante, y la propiedad a la que necesita acceder depende de si está utilizando la API web bajo IIS (alojado en la web) o autohospedado. El siguiente código muestra cómo se puede hacer esto.

 private string GetClientIp(HttpRequestMessage request) { if (request.Properties.ContainsKey("MS_HttpContext")) { return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress; } if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name)) { RemoteEndpointMessageProperty prop; prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name]; return prop.Address; } return null; } 

Esta solución también cubre la API web autohospedada utilizando Owin. Parcialmente desde aquí .

Puede crear un método privado en su ApiController que le devuelva una dirección IP remota independientemente de cómo aloje su API web:

  private const string HttpContext = "MS_HttpContext"; private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty"; private const string OwinContext = "MS_OwinContext"; private string GetClientIp(HttpRequestMessage request) { // Web-hosting if (request.Properties.ContainsKey(HttpContext )) { HttpContextWrapper ctx = (HttpContextWrapper)request.Properties[HttpContext]; if (ctx != null) { return ctx.Request.UserHostAddress; } } // Self-hosting if (request.Properties.ContainsKey(RemoteEndpointMessage)) { RemoteEndpointMessageProperty remoteEndpoint = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessage]; if (remoteEndpoint != null) { return remoteEndpoint.Address; } } // Self-hosting using Owin if (request.Properties.ContainsKey(OwinContext)) { OwinContext owinContext = (OwinContext)request.Properties[OwinContext]; if (owinContext != null) { return owinContext.Request.RemoteIpAddress; } } return null; } 

Referencias requeridas:

  • HttpContextWrapper – System.Web.dll
  • RemoteEndpointMessageProperty – System.ServiceModel.dll
  • OwinContext – Microsoft.Owin.dll (ya lo tendrá si usa el paquete Owin)

Un pequeño problema con esta solución es que tiene que cargar bibliotecas para los 3 casos en los que solo utilizará uno de ellos durante el tiempo de ejecución. Como se sugiere aquí , esto puede superarse mediante el uso de variables dynamic . También puede escribir el método GetClientIpAddress como una extensión para HttpRequestMethod .

 using System.Net.Http; public static class HttpRequestMessageExtensions { private const string HttpContext = "MS_HttpContext"; private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty"; private const string OwinContext = "MS_OwinContext"; public static string GetClientIpAddress(this HttpRequestMessage request) { // Web-hosting. Needs reference to System.Web.dll if (request.Properties.ContainsKey(HttpContext)) { dynamic ctx = request.Properties[HttpContext]; if (ctx != null) { return ctx.Request.UserHostAddress; } } // Self-hosting. Needs reference to System.ServiceModel.dll. if (request.Properties.ContainsKey(RemoteEndpointMessage)) { dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage]; if (remoteEndpoint != null) { return remoteEndpoint.Address; } } // Self-hosting using Owin. Needs reference to Microsoft.Owin.dll. if (request.Properties.ContainsKey(OwinContext)) { dynamic owinContext = request.Properties[OwinContext]; if (owinContext != null) { return owinContext.Request.RemoteIpAddress; } } return null; } } 

Ahora puedes usarlo así:

 public class TestController : ApiController { [HttpPost] [ActionName("TestRemoteIp")] public string TestRemoteIp() { return Request.GetClientIpAddress(); } } 

Si realmente quieres un one-liner y no planeas auto-hospedar Web API:

 ((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress; 

Las respuestas anteriores requieren una referencia a System.Web para poder convertir la propiedad a HttpContext o HttpContextWrapper. Si no quiere la referencia, puede obtener la ip usando una dinámica:

 var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress; 

La solución provista por carlosfigueira funciona, pero las líneas simples de tipo seguro son mejores: agregue una using System.Web luego acceda a HttpContext.Current.Request.UserHostAddress en su método de acción.