获取远程主机的IP地址

在ASP.NET中有一个System.Web.HttpRequest类,它包含ServerVariables属性,它可以为我们提供REMOTE_ADDR属性值的IP地址。

但是,我找不到从ASP.NET Web API获取远程主机的IP地址的类似方法。

如何获取发出请求的远程主机的IP地址?

有可能做到这一点,但不是很容易发现 – 您需要使用传入请求中的资源包,并且您需要访问的属性取决于您使用IIS(WebHosted)下的Web API还是自托pipe的Web API。 下面的代码显示了如何做到这一点。

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

该解决scheme还涵盖了使用Owin自主托pipe的Web API。 部分从这里 。

您可以在您的ApiController中创build一个私有方法,无论您如何托pipe您的Web API,它都将返回远程IP地址:

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

所需参考:

  • HttpContextWrapper – System.Web.dll
  • RemoteEndpointMessageProperty – System.ServiceModel.dll
  • OwinContext – Microsoft.Owin.dll(如果你使用Owin包,你将拥有它)

这个解决scheme的一个小问题是,如果在运行时实际只使用其中的一种,则必须为所有3种情况加载库。 正如这里所build议的,这可以通过使用dynamicvariables来克服。 您也可以编写GetClientIpAddress方法作为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; } } 

现在你可以像这样使用它:

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

如果你真的想要一个单线程而不打算自主托pipeWeb API:

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

以上答案需要System.Web的引用才能将该属性强制转换为HttpContext或HttpContextWrapper。 如果你不想参考,你可以使用dynamic获取IP:

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

由carlosfigueira提供的解决scheme工作,但types安全的单行是更好的:添加一个using System.Web然后访问HttpContext.Current.Request.UserHostAddress在您的操作方法。