重点是拿到HttpContext 对象。
先从Headers["Cdn-Src-Ip"] 中取IP,其次从Headers["X-Forwarded-For"] 取,最后从context.Connection.RemoteIpAddress 中取。
有可能遇到“::ffff:192.168.2.131” 这种IP,把"::ffff:"Replace掉。
工具类CoreMvcClientIpUtil:
namespace CommonUtils { public static class CoreMvcClientIpUtil { public static string GetClientIP(HttpContext context) { var ip = context.Request.Headers["Cdn-Src-Ip"].FirstOrDefault(); if (!string.IsNullOrEmpty(ip)) return IpReplace(ip); ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); if (!string.IsNullOrEmpty(ip)) return IpReplace(ip); ip = context.Connection.RemoteIpAddress.ToString(); return IpReplace(ip); } static string IpReplace(string inip) { //::ffff: //::ffff:192.168.2.131 这种IP处理 if (inip.Contains("::ffff:")) { inip = inip.Replace("::ffff:", ""); } return inip; } } }
一、使用HttpContextAccessor
在Program.cs中增加一行:
//获取IP使用
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllersWithViews(); //获取IP使用 builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run();
修改Controller:
全局变量增加
private readonly IHttpContextAccessor _httpContextAccessor;
构造函数增加
_httpContextAccessor = httpContextAccessor;
Action中获取IP
var ip = CoreMvcClientIpUtil.GetClientIP(_httpContextAccessor.HttpContext);
using CommonUtils; using CommonUtils.Extensions; using Microsoft.AspNetCore.Mvc; namespace AspNetCoreMvcClientIp2.Controllers { public class OkController : Controller { private readonly IHttpContextAccessor _httpContextAccessor; public OkController(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } // GET: OkController public ActionResult Index() { var ip = CoreMvcClientIpUtil.GetClientIP(_httpContextAccessor.HttpContext); ViewBag.myip1 = "ip:" + ip; //直接实例化HttpContextAccessor IHttpContextAccessor ih = new HttpContextAccessor(); string ip2 = CoreMvcClientIpUtil.GetClientIP(ih.HttpContext); ViewBag.myip2 = "ip2:" + ip2; //使用ControllerBase的HttpContext var ip3 = CoreMvcClientIpUtil.GetClientIP(HttpContext); ViewBag.myip3 = "ip3:" + ip3; //扩展方法 var ip4 = HttpContext.GetClientIP(); ViewBag.myip4 = "ip4:" + ip4; return View(); } } }
也可以直接实例化HttpContextAccessor:
IHttpContextAccessor ih = new HttpContextAccessor(); string ip2 = CoreMvcClientIpUtil.GetClientIP(ih.HttpContext);
二、使用ControllerBase的HttpContext
//使用ControllerBase的HttpContext var ip3 = CoreMvcClientIpUtil.GetClientIP(HttpContext); ViewBag.myip3 = "ip3:" + ip3;
三、扩展HttpContext
using Microsoft.AspNetCore.Http; namespace CommonUtils.Extensions { public static class HttpContextExtension { public static string GetClientIP(this HttpContext context) { var ip = context.Request.Headers["Cdn-Src-Ip"].FirstOrDefault(); if (!string.IsNullOrEmpty(ip)) return IpReplace(ip); ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault(); if (!string.IsNullOrEmpty(ip)) return IpReplace(ip); ip = context.Connection.RemoteIpAddress.ToString(); return IpReplace(ip); } static string IpReplace(string inip) { //::ffff: //::ffff:192.168.2.131 这种IP处理 if (inip.Contains("::ffff:")) { inip = inip.Replace("::ffff:", ""); } return inip; } } }
在Controller中使用时要using CommonUtils.Extensions;
var ip4 = HttpContext.GetClientIP(); ViewBag.myip = "ip4:" + ip4;
。