请问如何在ASP中获取客户端IP地址?NET时使用MVC 6。 请求。ServerVariables["REMOTE_ADDR"]无效。
当前回答
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
public string GetClientIPAddress(HttpContext context)
{
string ip = string.Empty;
if (!string.IsNullOrEmpty(context.Request.Headers["X-Forwarded-For"]))
{
ip = context.Request.Headers["X-Forwarded-For"];
}
else
{
ip = context.Request.HttpContext.Features.Get<IHttpConnectionFeature>().RemoteIpAddress.ToString();
}
return ip;
}
你想获取Ip地址;
GetClientIPAddress(HttpContext);
其他回答
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
您可以使用IHttpConnectionFeature来获取此信息。
var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
@crokusek回答的简短版本
public string GetUserIP(HttpRequest req)
{
var ip = req.Headers["X-Forwarded-For"].FirstOrDefault();
if (!string.IsNullOrWhiteSpace(ip)) ip = ip.Split(',')[0];
if (string.IsNullOrWhiteSpace(ip)) ip = Convert.ToString(req.HttpContext.Connection.RemoteIpAddress);
if (string.IsNullOrWhiteSpace(ip)) ip = req.Headers["REMOTE_ADDR"].FirstOrDefault();
return ip;
}
在IIS上使用负载均衡器运行。net core(3.1.4)不能与其他建议的解决方案一起工作。
手动读取X-Forwarded-For报头可以。 这段代码假设这个报头包含一个IP。
IPAddress ip;
var headers = Request.Headers.ToList();
if (headers.Exists((kvp) => kvp.Key == "X-Forwarded-For"))
{
// when running behind a load balancer you can expect this header
var header = headers.First((kvp) => kvp.Key == "X-Forwarded-For").Value.ToString();
// in case the IP contains a port, remove ':' and everything after
ip = IPAddress.Parse(header.Remove(header.IndexOf(':')));
}
else
{
// this will always have a value (running locally in development won't have the header)
ip = Request.HttpContext.Connection.RemoteIpAddress;
}
感谢@JawadAlShaikh和@BozoJoe指出IP可以包含一个端口,x - forward - for可以包含多个IP。
可以添加一些回退逻辑来处理负载均衡器的存在。
此外,通过检查,即使没有负载均衡器,X-Forwarded-For报头也会被设置(可能是因为额外的Kestrel层?):
public string GetRequestIP(bool tryUseXForwardHeader = true)
{
string ip = null;
// todo support new "Forwarded" header (2014) https://en.wikipedia.org/wiki/X-Forwarded-For
// X-Forwarded-For (csv list): Using the First entry in the list seems to work
// for 99% of cases however it has been suggested that a better (although tedious)
// approach might be to read each IP from right to left and use the first public IP.
// http://stackoverflow.com/a/43554000/538763
//
if (tryUseXForwardHeader)
ip = GetHeaderValueAs<string>("X-Forwarded-For").SplitCsv().FirstOrDefault();
// RemoteIpAddress is always null in DNX RC1 Update1 (bug).
if (ip.IsNullOrWhitespace() && _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress != null)
ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
if (ip.IsNullOrWhitespace())
ip = GetHeaderValueAs<string>("REMOTE_ADDR");
// _httpContextAccessor.HttpContext?.Request?.Host this is the local host.
if (ip.IsNullOrWhitespace())
throw new Exception("Unable to determine caller's IP.");
return ip;
}
public T GetHeaderValueAs<T>(string headerName)
{
StringValues values;
if (_httpContextAccessor.HttpContext?.Request?.Headers?.TryGetValue(headerName, out values) ?? false)
{
string rawValues = values.ToString(); // writes out as Csv when there are multiple.
if (!rawValues.IsNullOrWhitespace())
return (T)Convert.ChangeType(values.ToString(), typeof(T));
}
return default(T);
}
public static List<string> SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false)
{
if (string.IsNullOrWhiteSpace(csvList))
return nullOrWhitespaceInputReturnsNull ? null : new List<string>();
return csvList
.TrimEnd(',')
.Split(',')
.AsEnumerable<string>()
.Select(s => s.Trim())
.ToList();
}
public static bool IsNullOrWhitespace(this string s)
{
return String.IsNullOrWhiteSpace(s);
}
假设_httpContextAccessor通过DI提供。
推荐文章
- 函数应该返回空对象还是空对象?
- 如何转换日期时间?将日期时间
- 如何在c#中连接列表?
- 在c#中引用类型变量的“ref”的用途是什么?
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 转换为值类型'Int32'失败,因为物化值为空
- c#中有任何连接字符串解析器吗?
- 在Linq中转换int到字符串到实体的问题
- 是否可以动态编译和执行c#代码片段?
- 创建自定义MSBuild任务时,如何从c#代码获取当前项目目录?
- c#和Java的主要区别是什么?
- 在c#中创建一个特定时区的DateTime
- .NET中的属性是什么?
- csproj文件中的“Service Include”是干什么用的?
- 如何使用try catch进行异常处理是最佳实践