Di ASP.NET ada System.Web.HttpRequest
kelas, yang berisi ServerVariables
properti yang dapat memberi kita alamat IP dari REMOTE_ADDR
nilai properti.
Namun, saya tidak dapat menemukan cara serupa untuk mendapatkan alamat IP dari host jarak jauh dari ASP.NET Web API.
Bagaimana saya bisa mendapatkan alamat IP dari host jarak jauh yang membuat permintaan?
c#
asp.net-web-api
paulius_l
sumber
sumber
RemoteEndpointMessageProperty
kelas diSystem.ServiceModel.Channels
namespace,System.ServiceModel.dll
assembly? Bukankah itu majelis milik WCF?Solusi ini juga mencakup API Web yang dihosting sendiri menggunakan Owin. Sebagian dari sini .
Anda dapat membuat metode privat dalam diri Anda
ApiController
yang akan mengembalikan alamat IP jarak jauh tidak peduli bagaimana Anda menghosting API Web Anda: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; }
Referensi diperlukan:
HttpContextWrapper
- System.Web.dllRemoteEndpointMessageProperty
- System.ServiceModel.dllOwinContext
- Microsoft.Owin.dll (Anda akan memilikinya jika Anda menggunakan paket Owin)Masalah kecil dengan solusi ini adalah Anda harus memuat pustaka untuk semua 3 kasus ketika Anda sebenarnya hanya akan menggunakan salah satu dari mereka selama runtime. Seperti yang disarankan di sini , ini dapat diatasi dengan menggunakan
dynamic
variabel. Anda juga dapat menulisGetClientIpAddress
metode sebagai ekstensiHttpRequestMethod
.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; } }
Sekarang Anda bisa menggunakannya seperti ini:
public class TestController : ApiController { [HttpPost] [ActionName("TestRemoteIp")] public string TestRemoteIp() { return Request.GetClientIpAddress(); } }
sumber
using System.Net.Http;
baris karena Anda memperluasHttpRequestMessage
. Kecuali Anda mendefinisikan ekstensi Anda diSystem.Net.Http
namespace yang sangat dipertanyakan. Tidak yakin itu penting, karena itu akan ditambahkan secara otomatis oleh IDE atau alat produktivitas apa pun. Bagaimana menurut anda?Jika Anda benar-benar menginginkan one-liner dan tidak berencana untuk menghosting API Web sendiri:
((System.Web.HttpContextWrapper)Request.Properties["MS_HttpContext"]).Request.UserHostAddress;
sumber
Jawaban di atas memerlukan referensi ke System.Web agar dapat mentransmisikan properti ke HttpContext atau HttpContextWrapper. Jika Anda tidak menginginkan referensi, Anda bisa mendapatkan ip menggunakan dinamika:
var host = ((dynamic)request.Properties["MS_HttpContext"]).Request.UserHostAddress;
sumber
Solusi yang disediakan oleh carlosfigueira berfungsi, tetapi satu baris yang aman untuk tipe lebih baik: Tambahkan
using System.Web
kemudian aksesHttpContext.Current.Request.UserHostAddress
ke metode tindakan Anda.sumber
HttpContext.Current
dengan benar di seluruh alur tugas; karena semua penanganan permintaan bersifat asinkron.HttpContext.Current
harus hampir selalu dihindari saat menulis kode API Web.SynchronizationContext
dialirkan dengan benar antar tugas); Masalah terbesar dengan ini adalah jika kode layanan Anda kemungkinan besar akan dihosting sendiri (pengujian, misalnya) -HttpContext.Current
merupakan konstruksi Asp.Net murni dan tidak ada saat Anda menghosting sendiri.NullReferenceException
jika digunakan dari utas (mis. Tugas awaiter, sangat umum dalam kode API Web modern) atau dalam konteks yang dihosting sendiri. Setidaknya sebagian besar jawaban lain akan kembalinull
.