C# 获取远程主机的IP地址
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9565889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get the IP address of the remote host
提问by paulius_l
In ASP.NET there is a System.Web.HttpRequestclass, which contains ServerVariablesproperty which can provide us the IP address from REMOTE_ADDRproperty value.
在 ASP.NET 中有一个System.Web.HttpRequest类,其中包含ServerVariables可以从REMOTE_ADDR属性值中为我们提供 IP 地址的属性。
However, I could not find a similar way to get the IP address of the remote host from ASP.NET Web API.
但是,我找不到类似的方法来从 ASP.NET Web API 获取远程主机的 IP 地址。
How can I get the IP address of the remote host that is making the request?
如何获取发出请求的远程主机的 IP 地址?
采纳答案by carlosfigueira
It's possible to do that, but not very discoverable - you need to use the property bag from the incoming request, and the property you need to access depends on whether you're using the Web API under IIS (webhosted) or self-hosted. The code below shows how this can be done.
这样做是可能的,但不是很容易发现 - 您需要使用传入请求中的属性包,您需要访问的属性取决于您是使用 IIS(网络托管)下的 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;
}
回答by Warren Rumak
The solution provided by carlosfigueira works, but type-safe one-liners are better: Add a using System.Webthen access HttpContext.Current.Request.UserHostAddressin your action method.
carlosfigueira 提供的解决方案有效,但类型安全的单行更好:在您的操作方法中添加using System.Webthen 访问HttpContext.Current.Request.UserHostAddress。
回答by zacharydl
If you really want a one-liner and don't plan to self-host Web API:
如果你真的想要一个单线并且不打算自托管 Web API:
((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
回答by Nikolai Samteladze
This solution also covers Web API self-hosted using Owin. Partially from here.
该解决方案还涵盖了使用 Owin 自托管的 Web API。部分来自这里。
You can create a private method in you ApiControllerthat will return remote IP address no matter how you host your Web API:
您可以在您内部创建一个私有方法,ApiController无论您如何托管 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;
}
References required:
所需参考资料:
HttpContextWrapper- System.Web.dllRemoteEndpointMessageProperty- System.ServiceModel.dllOwinContext- Microsoft.Owin.dll (you will have it already if you use Owin package)
HttpContextWrapper- System.Web.dllRemoteEndpointMessageProperty- System.ServiceModel.dllOwinContext- Microsoft.Owin.dll(如果您使用 Owin 包,您将已经拥有它)
A little problem with this solution is that you have to load libraries for all 3 cases when you will actually be using only one of them during runtime. As suggested here, this can be overcome by using dynamicvariables. You can also write GetClientIpAddressmethod as an extension for HttpRequestMethod.
此解决方案的一个小问题是您必须为所有 3 种情况加载库,而实际上您在运行时实际上只使用其中一种。正如这里所建议的,这可以通过使用dynamic变量来克服。您还可以编写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;
}
}
Now you can use it like this:
现在你可以像这样使用它:
public class TestController : ApiController
{
[HttpPost]
[ActionName("TestRemoteIp")]
public string TestRemoteIp()
{
return Request.GetClientIpAddress();
}
}
回答by Robin van der Knaap
Above answers require a reference to System.Web to be able to cast the property to HttpContext or HttpContextWrapper. If you don't want the reference, you are able to get the ip using a dynamic:
以上答案需要对 System.Web 的引用才能将属性转换为 HttpContext 或 HttpContextWrapper。如果您不想要引用,您可以使用动态获取 ip:
var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress;

