ASP.NET MVC 中的 HttpModule 生命周期

发布于 2024-10-01 05:44:00 字数 3378 浏览 0 评论 0原文

我找到了一个关于在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

七禾 2024-10-08 05:44:00

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

萌︼了一个春 2024-10-08 05:44:00

也许您正在使用 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文