ASP.NET MVC 中的 HttpModule 生命周期
我找到了一个关于在 Asp.Net 中统计在线用户的代码。我将其添加到我的 MVC 项目中,但它不起作用。有一个自定义 Httpmodule,它具有 Init() 函数,并且在每个请求中都会调用它。问题出在哪里。
init() 必须在所有应用程序生命周期中运行一次,但它会针对每个请求运行。 该代码在 asp.net 上运行良好,但由于 init() 方法在每个请求中运行,因此它无法在 MVC 上运行。
public class OnlineUsersModule : IHttpModule
{
private static Int32 _sessionTimeOut = 20; // Set Default to 20 Minutes
private static List<OnlineUserInfo> _onlineUsers = null;
public static List<OnlineUserInfo> OnlineUsers
{
get
{
CleanExpiredSessions();
return _onlineUsers;
}
}
private static void CleanExpiredSessions()
{
_onlineUsers.RemoveAll(delegate(OnlineUserInfo user)
{
return user.SessionStarted.AddMinutes(_sessionTimeOut) < DateTime.Now;
});
}
#region IHttpModule Members
public void Init(HttpApplication context)
{
_onlineUsers = new List<OnlineUserInfo>();
// Get the Current Session State Module
SessionStateModule module = context.Modules["Session"] as SessionStateModule;
module.Start += new EventHandler(Session_Start);
}
private void Session_Start(object sender, EventArgs e)
{
HttpRequest Request = HttpContext.Current.Request;
HttpApplicationState Application = HttpContext.Current.Application;
HttpSessionState Session = HttpContext.Current.Session;
// Get Session TimeOut
_sessionTimeOut = HttpContext.Current.Session.Timeout;
Application.Lock();
OnlineUserInfo user = new OnlineUserInfo();
user.SessionId = Session.SessionID;
user.SessionStarted = DateTime.Now;
user.UserAgent = !String.IsNullOrEmpty(Request.UserAgent)
? Request.UserAgent : String.Empty;
user.IPAddress = !String.IsNullOrEmpty(Request.UserHostAddress)
? Request.UserHostAddress : String.Empty;
if (Request.UrlReferrer != null)
{
user.UrlReferrer = !String.IsNullOrEmpty(Request.UrlReferrer.OriginalString)
? Request.UrlReferrer.OriginalString : String.Empty;
}
else
{
user.UrlReferrer = String.Empty;
}
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
user.CurrentUser = HttpContext.Current.User;
}
// Add the New User to Collection
_onlineUsers.Add(user);
Application.UnLock();
}
public void Dispose()
{
}
#endregion
}
public class OnlineUserInfo
{
public String UserAgent { get; set; }
public String SessionId { get; set; }
public String IPAddress { get; set; }
public String UrlReferrer { get; set; }
public DateTime SessionStarted { get; set; }
public IPrincipal CurrentUser { get; set; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("UserAgent = {0} | ", UserAgent);
sb.AppendFormat("SessionId = {0} | ", SessionId);
sb.AppendFormat("IPAddress = {0} | ", IPAddress);
sb.AppendFormat("UrlReferrer = {0} | ", UrlReferrer);
sb.AppendFormat("SessionStarted = {0}", SessionStarted);
return sb.ToString();
}
}
另外我认为还有一个问题。当我向 init() 方法添加断点时,按 F10 后它会转到 init() 的开始,这意味着还有其他线程尝试运行 init() 这是一个问题吗?
I find a code about counting online users in Asp.Net. I add it to my MVC project but its not working. There is a custom Httpmodule that has a Init() function and it is being called in every request. where is the problem.
init() must be run one time for all application lifecycle , but it is running on every request.
This code run well on asp.net but because of init() method run in every request it is not working on MVC.
public class OnlineUsersModule : IHttpModule
{
private static Int32 _sessionTimeOut = 20; // Set Default to 20 Minutes
private static List<OnlineUserInfo> _onlineUsers = null;
public static List<OnlineUserInfo> OnlineUsers
{
get
{
CleanExpiredSessions();
return _onlineUsers;
}
}
private static void CleanExpiredSessions()
{
_onlineUsers.RemoveAll(delegate(OnlineUserInfo user)
{
return user.SessionStarted.AddMinutes(_sessionTimeOut) < DateTime.Now;
});
}
#region IHttpModule Members
public void Init(HttpApplication context)
{
_onlineUsers = new List<OnlineUserInfo>();
// Get the Current Session State Module
SessionStateModule module = context.Modules["Session"] as SessionStateModule;
module.Start += new EventHandler(Session_Start);
}
private void Session_Start(object sender, EventArgs e)
{
HttpRequest Request = HttpContext.Current.Request;
HttpApplicationState Application = HttpContext.Current.Application;
HttpSessionState Session = HttpContext.Current.Session;
// Get Session TimeOut
_sessionTimeOut = HttpContext.Current.Session.Timeout;
Application.Lock();
OnlineUserInfo user = new OnlineUserInfo();
user.SessionId = Session.SessionID;
user.SessionStarted = DateTime.Now;
user.UserAgent = !String.IsNullOrEmpty(Request.UserAgent)
? Request.UserAgent : String.Empty;
user.IPAddress = !String.IsNullOrEmpty(Request.UserHostAddress)
? Request.UserHostAddress : String.Empty;
if (Request.UrlReferrer != null)
{
user.UrlReferrer = !String.IsNullOrEmpty(Request.UrlReferrer.OriginalString)
? Request.UrlReferrer.OriginalString : String.Empty;
}
else
{
user.UrlReferrer = String.Empty;
}
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
user.CurrentUser = HttpContext.Current.User;
}
// Add the New User to Collection
_onlineUsers.Add(user);
Application.UnLock();
}
public void Dispose()
{
}
#endregion
}
public class OnlineUserInfo
{
public String UserAgent { get; set; }
public String SessionId { get; set; }
public String IPAddress { get; set; }
public String UrlReferrer { get; set; }
public DateTime SessionStarted { get; set; }
public IPrincipal CurrentUser { get; set; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("UserAgent = {0} | ", UserAgent);
sb.AppendFormat("SessionId = {0} | ", SessionId);
sb.AppendFormat("IPAddress = {0} | ", IPAddress);
sb.AppendFormat("UrlReferrer = {0} | ", UrlReferrer);
sb.AppendFormat("SessionStarted = {0}", SessionStarted);
return sb.ToString();
}
}
Also I think there is one more problem. when i add breakpoint to init() method, after push F10 it goes to start of init() means there is other threads that try to run init() is it a problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
HttpModule 存在于池中。当您的应用程序启动并将其放入池中时,ASP.NET 进程会创建并初始化一定数量的(可配置的)它们。
然后,每次收到请求时,都会从池中取出一个实例并分配该实例来服务该请求。此时没有初始化。当请求处理完成后,实例将被放回池中以供以后使用。
在重负载下,系统可以决定创建更多 HttpModules
HTH实例
HttpModules live in a pool. The ASP.NET process creates and initializes a (configurable) number of them when your app starts up and places it in a pool.
Then every time a request comes in an instance is taken from the pool and assigned to service the request. There is no initialization at this time. When the processing of the request is completed, the instance is placed back in the pool for later use.
Under heavy load the system can decide to create more instances of HttpModules
HTH
也许您正在使用 Cassini 并每次按 F5 重新编译应用程序,这会产生每次请求都会调用
Init
方法的错觉。Maybe you are using Cassini and recompiling your application every time by hitting F5 which creates the illusion that the
Init
method is called on every request.