pau*_*s_l 133 c# asp.net-web-api
在ASP.NET中有一个System.Web.HttpRequest类,它包含ServerVariables可以从REMOTE_ADDR属性值为我们提供IP地址的属性.
但是,我找不到类似的方法从ASP.NET Web API获取远程主机的IP地址.
如何获取发出请求的远程主机的IP地址?
car*_*ira 186
可以这样做,但不是很容易被发现 - 您需要使用传入请求中的属性包,并且您需要访问的属性取决于您是在IIS(webhosted)下使用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;
}
Run Code Online (Sandbox Code Playgroud)
Nik*_*dze 73
此解决方案还涵盖使用Owin自托管的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;
}
Run Code Online (Sandbox Code Playgroud)
所需参考:
HttpContextWrapper - System.Web.dllRemoteEndpointMessageProperty - System.ServiceModel.dllOwinContext - Microsoft.Owin.dll(如果你使用Owin包,你会拥有它)这个解决方案的一个小问题是,当你在运行时实际只使用其中一个时,你必须为所有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;
}
}
Run Code Online (Sandbox Code Playgroud)
现在您可以像这样使用它:
public class TestController : ApiController
{
[HttpPost]
[ActionName("TestRemoteIp")]
public string TestRemoteIp()
{
return Request.GetClientIpAddress();
}
}
Run Code Online (Sandbox Code Playgroud)
zac*_*ydl 31
如果你真的想要一个单行并且不打算自托管Web API:
((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
Run Code Online (Sandbox Code Playgroud)
Rob*_*aap 13
以上答案需要引用System.Web才能将属性强制转换为HttpContext或HttpContextWrapper.如果您不想要引用,则可以使用动态获取ip:
var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
75656 次 |
| 最近记录: |