如何在ASP中获取客户端的IP地址?净MVC吗?

我对ASP完全不熟悉。NET MVC堆栈,我想知道发生了什么简单的页面对象和请求ServerVariables对象?

基本上,我想拉出客户端PC的IP地址,但我不明白当前的MVC结构如何改变了这一切。

据我所知,大多数变量对象已经被HttpRequest变量所取代

有人愿意分享一些资源吗?在ASP中有很多东西可以学习。NET MVC世界。:)

例如,我有一个带有当前函数的静态类。我如何得到相同的结果使用ASP。净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;
}

我如何从控制器页面调用这个函数?

285439 次浏览

Request.ServerVariables["REMOTE_ADDR"]应该工作-直接在视图中或在控制器动作方法体中(Request是MVC中controller类的属性,而不是Page)。

它正在工作…但是你必须在真实的IIS上发布,而不是虚拟的IIS。

简单的答案是使用HttpRequest。UserHostAddress财产

例子:从控制器内部:

using System;
using System.Web.Mvc;


namespace Mvc.Controllers
{
public class HomeController : ClientController
{
public ActionResult Index()
{
string ip = Request.UserHostAddress;


...
}
}
}

例子:从一个helper类中:

using System.Web;


namespace Mvc.Helpers
{
public static class HelperClass
{
public static string GetIPHelper()
{
string ip = HttpContext.Current.Request.UserHostAddress;
..
}
}
}

但是,如果请求已被一个或多个代理服务器传递,则HttpRequest。UserHostAddress财产返回的IP地址将是转发该请求的最后一个代理服务器的IP地址。

代理服务器五月使用事实上的标准将客户端的IP地址放在X-Forwarded-For HTTP报头中。除了不能保证请求有X-Forwarded-For报头外,也不能保证X-Forwarded-For没有< >强欺骗< / >强


原来的答案

Request.UserHostAddress

上面的代码提供了Client的IP地址,而不需要查找集合。Request属性在控制器(或视图)中可用。因此,你可以传递一个Request对象来获得相同的结果,而不是传递一个Page类给你的函数:

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;
}

在一个类中,你可以这样称呼它:

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;
}

我在一个剃须刀应用程序中使用了这个方法,效果很好。

我在使用上面的方法时遇到了麻烦,我需要控制器上的IP地址。最后我使用了以下方法:

System.Web.HttpContext.Current.Request.UserHostAddress

这里的许多代码都非常有用,但我根据自己的目的对其进行了清理,并添加了一些测试。这是我最后得出的结论:

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 mock来模拟HttpRequestBase,这是M<HttpRequestBase>调用如下):

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);
}
}

我如何解释我的网站背后的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;
}
}