こんにちは、Web APIで何らかのメソッドを要求するクライアントIPを取得する必要があります。このコードを here から使用しようとしましたが、常にサーバーのローカルIPを返します。正しい方法で取得するには?
HttpContext.Current.Request.UserHostAddress;
他の質問から:
public static class HttpRequestMessageExtensions
{
private const string HttpContext = "MS_HttpContext";
private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
public static string GetClientIpAddress(this HttpRequestMessage request)
{
if (request.Properties.ContainsKey(HttpContext))
{
dynamic ctx = request.Properties[HttpContext];
if (ctx != null)
{
return ctx.Request.UserHostAddress;
}
}
if (request.Properties.ContainsKey(RemoteEndpointMessage))
{
dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
if (remoteEndpoint != null)
{
return remoteEndpoint.Address;
}
}
return null;
}
}
次のリンクはあなたを助けるかもしれません。以下のリンクからのコードです。
参照: getting-the-client-ip-via-asp-net-web-api
using System.Net.Http;
using System.ServiceModel.Channels;
using System.Web;
using System.Web.Http;
namespace Trikks.Controllers.Api
{
public class IpController : ApiController
{
public string GetIp()
{
return GetClientIp();
}
private string GetClientIp(HttpRequestMessage request = null)
{
request = request ?? Request;
if (request.Properties.ContainsKey("MS_HttpContext"))
{
return ((HttpContextWrapper)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
}
else if (request.Properties.ContainsKey(RemoteEndpointMessageProperty.Name))
{
RemoteEndpointMessageProperty prop = (RemoteEndpointMessageProperty)request.Properties[RemoteEndpointMessageProperty.Name];
return prop.Address;
}
else if (HttpContext.Current != null)
{
return HttpContext.Current.Request.UserHostAddress;
}
else
{
return null;
}
}
}
}
これを行う別の方法は以下のとおりです。
Webホストバージョンの場合
string clientAddress = HttpContext.Current.Request.UserHostAddress;
セルフホストの場合
object property;
Request.Properties.TryGetValue(typeof(RemoteEndpointMessageProperty).FullName, out property);
RemoteEndpointMessageProperty remoteProperty = property as RemoteEndpointMessageProperty;
Web API 2.2の場合:Request.GetOwinContext().Request.RemoteIpAddress
を使用してIPを取得してみてください
ip = HttpContext.Current != null ? HttpContext.Current.Request.UserHostAddress : "";
OWIN Self-Host NuGetパッケージを使用してAsp.Net 2.1でセルフホスティングしている場合は、次のコードを使用できます。
private string getClientIp(HttpRequestMessage request = null)
{
if (request == null)
{
return null;
}
if (request.Properties.ContainsKey("MS_OwinContext"))
{
return ((OwinContext) request.Properties["MS_OwinContext"]).Request.RemoteIpAddress;
}
return null;
}
それをHttpContextBase
にキャストする方が良いです。そうすれば、もっと簡単にモックしてテストできます
public string GetUserIp(HttpRequestMessage request)
{
if (request.Properties.ContainsKey("MS_HttpContext"))
{
var ctx = request.Properties["MS_HttpContext"] as HttpContextBase;
if (ctx != null)
{
return ctx.Request.UserHostAddress;
}
}
return null;
}
私はこれが拡張方法を使用した最も明確な解決策だと思います:
public static class HttpRequestMessageExtensions
{
private const string HttpContext = "MS_HttpContext";
private const string RemoteEndpointMessage = "System.ServiceModel.Channels.RemoteEndpointMessageProperty";
public static string GetClientIpAddress(this HttpRequestMessage request)
{
if (request.Properties.ContainsKey(HttpContext))
{
dynamic ctx = request.Properties[HttpContext];
if (ctx != null)
{
return ctx.Request.UserHostAddress;
}
}
if (request.Properties.ContainsKey(RemoteEndpointMessage))
{
dynamic remoteEndpoint = request.Properties[RemoteEndpointMessage];
if (remoteEndpoint != null)
{
return remoteEndpoint.Address;
}
}
return null;
}
}
したがって、次のように使用します。
var ipAddress = request.GetClientIpAddress();
これをプロジェクトで使用します。
ソース/リファレンス: ASP.NET Web APIでクライアントのIPアドレスを取得
この4年前の投稿に返信すると、少なくともIISでホストしていて、この投稿がDuckDuckGo(およびおそらくNSAoogle)で「web api controller get IP住所"。
ここに私がそれを解決した方法があります:
using System;
using System.Net;
using System.Web;
using System.Web.Http;
...
[HttpPost]
[Route("ContactForm")]
public IHttpActionResult PostContactForm([FromBody] ContactForm contactForm)
{
var hostname = HttpContext.Current.Request.UserHostAddress;
IPAddress ipAddress = IPAddress.Parse(hostname);
IPHostEntry ipHostEntry = Dns.GetHostEntry(ipAddress);
...
OPとは異なり、これはサーバーではなくクライアントIPとクライアントホスト名を提供します。おそらく彼らはそれ以来バグを修正したのでしょうか?
私のソリューションはuser1587439の答えに似ていますが、(HttpContext.Currentにアクセスする代わりに)コントローラのインスタンスで直接動作します。
「ウォッチ」ウィンドウで、this.RequestContext.WebRequestに「UserHostAddress」プロパティが含まれていることがわかりましたが、WebHostHttpRequestContextタイプ(「System.Web.Http」アセンブリの内部)に依存しているため、そうではありませんでした直接アクセスできるため、リフレクションを使用して直接アクセスします。
string hostAddress = ((System.Web.HttpRequestWrapper)this.RequestContext.GetType().Assembly.GetType("System.Web.Http.WebHost.WebHostHttpRequestContext").GetProperty("WebRequest").GetMethod.Invoke(this.RequestContext, null)).UserHostAddress;
私はそれが最善の解決策だと言っているわけではありません。フレームワークのアップグレード(名前の変更による)の場合、リフレクションを使用すると将来的に問題が発生する可能性がありますが、私のニーズには完璧です