Как я могу получить IP-адрес клиента ASP.NET MVC?
Я совершенно новичок в ASP.NET стек MVC, и мне было интересно, что случилось с простым объектом страницы и объектом запроса ServerVariables?
в принципе, я хочу вытащить IP-адрес клиентского ПК, но я не понимаю, как текущая структура MVC изменила все это.
насколько я понимаю, большинство переменных объектов были заменены вариантами HttpRequest.
кто-нибудь хочет поделиться ресурсы? Существует действительно море вещей, чтобы узнать в ASP.NET мир MVC. :)
например, у меня есть статический класс С этот текущей функции. Как я могу получить тот же результат с помощью ASP.NET MVC?
public static int getCountry(Page page)
{
return getCountryFromIP(getIPAddress(page));
}
public static string getIPAddress(Page page)
{
string szRemoteAddr = page.Request.ServerVariables["REMOTE_ADDR"];
string szXForwardedFor = page.Request.ServerVariables["X_FORWARDED_FOR"];
string szIP = "";
if (szXForwardedFor == null)
{
szIP = szRemoteAddr;
}
else
{
szIP = szXForwardedFor;
if (szIP.IndexOf(",") > 0)
{
string [] arIPs = szIP.Split(',');
foreach (string item in arIPs)
{
if (!isPrivateIP(item))
{
return item;
}
}
}
}
return szIP;
}
и как я могу вызвать эту функцию, на странице контроллера?
6 ответов:
самый простой ответ заключается в использовании HttpRequest.UserHostAddress собственность.
пример: внутри контроллера:
using System; using System.Web.Mvc; namespace Mvc.Controllers { public class HomeController : ClientController { public ActionResult Index() { string ip = Request.UserHostAddress; ... } } }пример: из вспомогательного класса:
using System.Web; namespace Mvc.Helpers { public static class HelperClass { public static string GetIPHelper() { string ip = HttpContext.Current.Request.UserHostAddress; .. } } }а, если запрос был передан одним или несколькими, прокси-серверы затем IP-адрес возвращается HttpRequest.UserHostAddress собственность будет IP-адрес последнего прокси-сервер, который перенаправляет запрос.
прокси-серверы мая использовать де-факто стандарт размещения IP-адреса клиента в X-Forwarded-For заголовок HTTP. Кроме того, нет никакой гарантии, что запрос имеет заголовок X-Forwarded-For, также нет никакой гарантии, что X-Forwarded-For не был поддельный.
Оригинальный Ответ
Request.UserHostAddressв приведенный выше код предоставляет IP-адрес клиента, не прибегая к поиску коллекции. Свойство Request доступно в контроллерах (или представлениях). Поэтому вместо передачи класса страницы в функцию можно передать объект запроса, чтобы получить тот же результат:
public static string getIPAddress(HttpRequestBase request) { string szRemoteAddr = request.UserHostAddress; string szXForwardedFor = request.ServerVariables["X_FORWARDED_FOR"]; string szIP = ""; if (szXForwardedFor == null) { szIP = szRemoteAddr; } else { szIP = szXForwardedFor; if (szIP.IndexOf(",") > 0) { string [] arIPs = szIP.Split(','); foreach (string item in arIPs) { if (!isPrivateIP(item)) { return item; } } } } return szIP; }
Request.ServerVariables["REMOTE_ADDR"]должно работать-либо непосредственно в представлении, либо в теле метода действия контроллера (запрос является свойством класса контроллера в MVC, а не страницы).это работает.. но вы должны публиковать на реальном IIS, а не на виртуальном.
много кода здесь было очень полезно, но я очистил его для своих целей и добавил некоторые тесты. Вот что у меня получилось:
using System; using System.Linq; using System.Net; using System.Web; public class RequestHelpers { public static string GetClientIpAddress(HttpRequestBase request) { try { var userHostAddress = request.UserHostAddress; // Attempt to parse. If it fails, we catch below and return "0.0.0.0" // Could use TryParse instead, but I wanted to catch all exceptions IPAddress.Parse(userHostAddress); var xForwardedFor = request.ServerVariables["X_FORWARDED_FOR"]; if (string.IsNullOrEmpty(xForwardedFor)) return userHostAddress; // Get a list of public ip addresses in the X_FORWARDED_FOR variable var publicForwardingIps = xForwardedFor.Split(',').Where(ip => !IsPrivateIpAddress(ip)).ToList(); // If we found any, return the last one, otherwise return the user host address return publicForwardingIps.Any() ? publicForwardingIps.Last() : userHostAddress; } catch (Exception) { // Always return all zeroes for any failure (my calling code expects it) return "0.0.0.0"; } } private static bool IsPrivateIpAddress(string ipAddress) { // http://en.wikipedia.org/wiki/Private_network // Private IP Addresses are: // 24-bit block: 10.0.0.0 through 10.255.255.255 // 20-bit block: 172.16.0.0 through 172.31.255.255 // 16-bit block: 192.168.0.0 through 192.168.255.255 // Link-local addresses: 169.254.0.0 through 169.254.255.255 (http://en.wikipedia.org/wiki/Link-local_address) var ip = IPAddress.Parse(ipAddress); var octets = ip.GetAddressBytes(); var is24BitBlock = octets[0] == 10; if (is24BitBlock) return true; // Return to prevent further processing var is20BitBlock = octets[0] == 172 && octets[1] >= 16 && octets[1] <= 31; if (is20BitBlock) return true; // Return to prevent further processing var is16BitBlock = octets[0] == 192 && octets[1] == 168; if (is16BitBlock) return true; // Return to prevent further processing var isLinkLocalAddress = octets[0] == 169 && octets[1] == 254; return isLinkLocalAddress; } }и вот некоторые тесты NUnit против этого кода (я использую Rhino Mocks, чтобы издеваться над HttpRequestBase, который является вызовом M
ниже): using System.Web; using NUnit.Framework; using Rhino.Mocks; using Should; [TestFixture] public class HelpersTests : TestBase { HttpRequestBase _httpRequest; private const string XForwardedFor = "X_FORWARDED_FOR"; private const string MalformedIpAddress = "MALFORMED"; private const string DefaultIpAddress = "0.0.0.0"; private const string GoogleIpAddress = "74.125.224.224"; private const string MicrosoftIpAddress = "65.55.58.201"; private const string Private24Bit = "10.0.0.0"; private const string Private20Bit = "172.16.0.0"; private const string Private16Bit = "192.168.0.0"; private const string PrivateLinkLocal = "169.254.0.0"; [SetUp] public void Setup() { _httpRequest = M<HttpRequestBase>(); } [TearDown] public void Teardown() { _httpRequest = null; } [Test] public void PublicIpAndNullXForwardedFor_Returns_CorrectIp() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(null); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(GoogleIpAddress); } [Test] public void PublicIpAndEmptyXForwardedFor_Returns_CorrectIp() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(string.Empty); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(GoogleIpAddress); } [Test] public void MalformedUserHostAddress_Returns_DefaultIpAddress() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(MalformedIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(null); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(DefaultIpAddress); } [Test] public void MalformedXForwardedFor_Returns_DefaultIpAddress() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(MalformedIpAddress); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(DefaultIpAddress); } [Test] public void SingleValidPublicXForwardedFor_Returns_XForwardedFor() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(MicrosoftIpAddress); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(MicrosoftIpAddress); } [Test] public void MultipleValidPublicXForwardedFor_Returns_LastXForwardedFor() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(GoogleIpAddress + "," + MicrosoftIpAddress); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(MicrosoftIpAddress); } [Test] public void SinglePrivateXForwardedFor_Returns_UserHostAddress() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(Private24Bit); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(GoogleIpAddress); } [Test] public void MultiplePrivateXForwardedFor_Returns_UserHostAddress() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); const string privateIpList = Private24Bit + "," + Private20Bit + "," + Private16Bit + "," + PrivateLinkLocal; _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(privateIpList); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(GoogleIpAddress); } [Test] public void MultiplePublicXForwardedForWithPrivateLast_Returns_LastPublic() { // Arrange _httpRequest.Stub(x => x.UserHostAddress).Return(GoogleIpAddress); const string privateIpList = Private24Bit + "," + Private20Bit + "," + MicrosoftIpAddress + "," + PrivateLinkLocal; _httpRequest.Stub(x => x.ServerVariables[XForwardedFor]).Return(privateIpList); // Act var ip = RequestHelpers.GetClientIpAddress(_httpRequest); // Assert ip.ShouldEqual(MicrosoftIpAddress); } }
У меня были проблемы с использованием выше, и мне нужен был IP-адрес от контроллера. Я использовал следующее В конце:
System.Web.HttpContext.Current.Request.UserHostAddress
в классе вы можете назвать это так:
public static string GetIPAddress(HttpRequestBase request) { string ip; try { ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (!string.IsNullOrEmpty(ip)) { if (ip.IndexOf(",") > 0) { string[] ipRange = ip.Split(','); int le = ipRange.Length - 1; ip = ipRange[le]; } } else { ip = request.UserHostAddress; } } catch { ip = null; } return ip; }я использовал это в приложении razor с отличными результатами.
Как я объясняю, что мой сайт находится за Amazon AWS эластичный балансировщик нагрузки (ELB):
public class GetPublicIp { /// <summary> /// account for possbility of ELB sheilding the public IP address /// </summary> /// <returns></returns> public static string Execute() { try { Console.WriteLine(string.Join("|", new List<object> { HttpContext.Current.Request.UserHostAddress, HttpContext.Current.Request.Headers["X-Forwarded-For"], HttpContext.Current.Request.Headers["REMOTE_ADDR"] }) ); var ip = HttpContext.Current.Request.UserHostAddress; if (HttpContext.Current.Request.Headers["X-Forwarded-For"] != null) { ip = HttpContext.Current.Request.Headers["X-Forwarded-For"]; Console.WriteLine(ip + "|X-Forwarded-For"); } else if (HttpContext.Current.Request.Headers["REMOTE_ADDR"] != null) { ip = HttpContext.Current.Request.Headers["REMOTE_ADDR"]; Console.WriteLine(ip + "|REMOTE_ADDR"); } return ip; } catch (Exception ex) { Console.Error.WriteLine(ex.Message); } return null; } }
Comments