답변:
그렇게 할 수는 있지만 검색 할 수는 없습니다. 들어오는 요청에서 속성 백을 사용해야하며 액세스 해야하는 속성은 IIS에서 웹 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;
}
RemoteEndpointMessageProperty
의 클래스 System.ServiceModel.Channels
, 네임 스페이스 System.ServiceModel.dll
조립? WCF에 속한 어셈블리가 아닙니까?
이 솔루션은 또한 Owin을 사용하여 자체 호스팅 된 웹 API를 다룹니다. 여기 에서 부분적으로 .
ApiController
웹 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.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;
}
}
이제 다음과 같이 사용할 수 있습니다.
public class TestController : ApiController
{
[HttpPost]
[ActionName("TestRemoteIp")]
public string TestRemoteIp()
{
return Request.GetClientIpAddress();
}
}
using System.Net.Http;
합니다 HttpRequestMessage
. System.Net.Http
네임 스페이스 에서 확장을 정의하지 않는 한 매우 의심 스럽습니다. IDE 또는 생산성 도구에 의해 자동으로 추가되므로 필수인지 확실하지 않습니다. 어떻게 생각해?
위의 답변에는 속성을 HttpContext 또는 HttpContextWrapper로 캐스팅하려면 System.Web에 대한 참조가 필요합니다. 참조를 원하지 않으면 동적을 사용하여 ip를 얻을 수 있습니다.
var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
carlosfigueira가 제공하는 솔루션은 효과가 있지만, 유형이 안전한 원 라이너가 더 좋습니다. 액션 방법에 using System.Web
액세스 권한 HttpContext.Current.Request.UserHostAddress
을 추가하십시오 .
HttpContext.Current
작업 파이프 라인에서 올바르게 유지되지 않으므로 웹 API에서 신뢰할 수 없습니다 . 모든 요청 처리가 비동기 적이므로 HttpContext.Current
웹 API 코드를 작성할 때 거의 항상 피해야합니다.
SynchronizationContext
작업간에 올바르게 흐름이있는 경우 항상 직접적이지는 않지만 ); 이것의 가장 큰 문제는 서비스 코드가 자체 호스팅 될 가능성이 높다는 것입니다 (예 : 테스트)- HttpContext.Current
순수한 Asp.Net 구조이며 자체 호스팅 할 때는 존재하지 않습니다.
NullReferenceException
스레드 (예 : 최신 웹 API 코드에서 매우 일반적인 작업 대기자) 또는 자체 호스팅 컨텍스트에서 사용되는 경우 디버그하기가 어렵습니다 . 적어도 대부분의 다른 답변은 반환 null
됩니다.