c# - servidor - Obtener la dirección IP del host remoto
obtener ip en asp net c# (5)
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 here .
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 here , 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();
}
}
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.
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;
Si realmente quieres un one-liner y no planeas auto-hospedar Web API:
((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress;