如何在DotVVM视图模型中获取远程用户IP地址
当然可以在视图模型中实现获取远程用户IP的功能!
结合你使用的DotVVM 1.1.9、ASP.NET Core及.NET Framework 4.7.1环境,具体操作步骤如下:
1. 转换DotVVM的IHttpContext为原生HttpContext
你说得没错,ViewModelBase的Context属性是DotVVM内置的IHttpContext接口,不过只要把它转换成DotvvmHttpContext,就能通过它的OriginalContext属性拿到原生的HttpContext对象(不管是ASP.NET Core的还是System.Web的)。
代码示例:
var dotvvmContext = (DotvvmHttpContext)Context; var originalHttpContext = dotvvmContext.OriginalContext;
2. 根据环境获取IP地址
因为你同时涉及ASP.NET Core和.NET Framework两种环境,需要分别处理:
针对ASP.NET Core环境
原生HttpContext是Microsoft.AspNetCore.Http.HttpContext,通过Connection.RemoteIpAddress获取IP:
var coreContext = (Microsoft.AspNetCore.Http.HttpContext)originalHttpContext; var remoteIp = coreContext.Connection.RemoteIpAddress?.ToString();
注意:如果你的应用部署在反向代理(如Nginx、IIS ARR)之后,直接拿到的会是代理服务器的IP。这时候需要先在Startup.cs中配置转发头中间件:
// 在Configure方法中添加 app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto });
配置完成后,RemoteIpAddress会自动返回真实的客户端IP。
针对.NET Framework(System.Web)环境
原生HttpContext是System.Web.HttpContext,可以通过Request.UserHostAddress直接获取:
var webContext = (System.Web.HttpContext)originalHttpContext; var remoteIp = webContext.Request.UserHostAddress;
同样处理反向代理场景:如果请求头包含X-Forwarded-For,优先取这个值的第一个IP(多个代理时会有逗号分隔的IP列表):
var forwardedFor = webContext.Request.Headers["X-Forwarded-For"]; if (!string.IsNullOrEmpty(forwardedFor)) { remoteIp = forwardedFor.Split(',')[0].Trim(); }
完整的ViewModel示例
把上面的逻辑整合到你的视图模型中,比如在OnInit方法里获取IP:
using DotVVM.Framework.Hosting; using Microsoft.AspNetCore.Http; // ASP.NET Core环境引用 // 或者 using System.Web; // .NET Framework环境引用 public class YourViewModel : ViewModelBase { public string UserIpAddress { get; set; } public override void OnInit() { base.OnInit(); var dotvvmContext = (DotvvmHttpContext)Context; var originalContext = dotvvmContext.OriginalContext; if (originalContext is Microsoft.AspNetCore.Http.HttpContext coreContext) { // ASP.NET Core环境逻辑 UserIpAddress = coreContext.Connection.RemoteIpAddress?.ToString(); } else if (originalContext is System.Web.HttpContext webContext) { // .NET Framework环境逻辑 UserIpAddress = webContext.Request.UserHostAddress; // 处理反向代理 var forwardedFor = webContext.Request.Headers["X-Forwarded-For"]; if (!string.IsNullOrEmpty(forwardedFor)) { UserIpAddress = forwardedFor.Split(',')[0].Trim(); } } } }
这个方案在DotVVM 1.1.9版本中完全可行,因为该版本的DotvvmHttpContext确实提供了OriginalContext属性来访问原生HttpContext。
内容的提问来源于stack exchange,提问作者Václav Holuša

