zoukankan      html  css  js  c++  java
  • web fromGlobal.asax(转)

    Global.asax(转)

    在ASP.NET梦工厂群中,有朋友寻网站当前在线人数和所有访问次数的代码,因为正好看到书上有这个例子就应了下来,结果却小弄了好一阵才搞定,不过还真有些需要注意的问题,在此总结,希望和大家共同交流。
        原本在VS2003中默认已经建立的web.config文件和Global.asax,在05下都需要手动添加了,下面就是添加 Global.asax 的界面:手动添加Global.asax

       
    下面是默认生成的Global.asax的代码,和03也有了些许不同,函数的声明也有了小变化。

    <%@ Application Language="C#" %>
    <script runat="server">
        void Application_Start(object sender, EventArgs e) 
        {
            // Code that runs on application startup
        }    
        void Application_End(object sender, EventArgs e) 
        {
            //  Code that runs on application shutdown
        }        
        void Application_Error(object sender, EventArgs e) 
        { 
            // Code that runs when an unhandled error occurs
        }
        void Session_Start(object sender, EventArgs e) 
        {
            // Code that runs when a new session is started
        }
        void Session_End(object sender, EventArgs e) 
        {
            // Code that runs when a session ends. 
            // Note: The Session_End event is raised only when the sessionstate mode
            // is set to InProc in the Web.config file. If session mode is set to StateServer 
            // or SQLServer, the event is not raised.
        }       
    </script>

        这里需要注意的是 Session_End 事件,只有 InProc 模式支持该事件,也就是说,只有将会话数据存储在 ASP.NET 辅助进程中时才支持该事件。它标志着会话的结束,并用于执行终止该会话所需的所有清除代码。对于要引发的 Session_End 事件来说,必须首先存在会话状态,这意味着必须在该会话状态中存储一些数据,并且必须至少完成一个请求。如果会话状态属性 Mode 为 StateServer 或 SQLServer,则忽略 Global.asax 文件中的 Session_End 事件。如果会话状态属性 Mode 设置为 Custom,则由自定义会话状态存储提供程序决定是否支持 Session_End 事件。
         会话状态的配置是通过设置Web.config文件的<sessionState>节来实现的。下面介绍一下进程内模式的配置方法,它也是默认的会话状态模式。若要使用进程内模式,请将 <sessionState> 元素的 mode 属性设置为 Inproc。
    下面显示了进程内模式的一个配置设置示例。

    <configuration>
        <system.web>
            <sessionState mode="Inproc"
                          cookieless="false"
                          timeout="20"/>
            </sessionState>
        </system.web>
    </configuration>

        下面是我的Global.asax的完整代码,其中在线统计的部分借鉴了 MSDN 中的方法,而没有使用 Session 对象,所有访问次数的统计是采用了读写文件的方式,需要在应用程序中加一个 Counter.txt 文本文件。
    <%@ Application Language="C#" %>
    <%@ Import Namespace="System.IO" %>

    <script runat="server">
        void Application_Start(object sender, EventArgs e) {
            Application["UsersOnline"] = 0;

            int count = 0;
            StreamReader srd;
            //取得文件的实际路径 
            string file_path = Server.MapPath("counter.txt");
            //打开文件进行读取 
            srd = File.OpenText(file_path);
            while (srd.Peek() != -1)
            {
                string str = srd.ReadLine();
                count = Int32.Parse(str);
            }
            object obj = count;
            Application["TotalCount"] = obj;
            srd.Close(); 
        }
        
        void Application_End(object sender, EventArgs e) 
        {
            int count = 0;
            count = (int)Application["TotalCount"];
            string file_path = Server.MapPath("counter.txt");
            StreamWriter fs = new StreamWriter(file_path, false);
            fs.WriteLine(count);
            fs.Close();
        }
            
        void Application_Error(object sender, EventArgs e) 
        { 
            // Code that runs when an unhandled error occurs

        }

        void Session_Start(object sender, EventArgs e) 
        {
            Application.Lock();
            Application["UsersOnline"] = (int)Application["UsersOnline"] + 1;

            //访问总数加1 
            int count = 0;
            count = (int)Application["TotalCount"];
            count = count + 1;
            Application["TotalCount"] = count;
            //将数据记录写入文件 
            string file_path = Server.MapPath("counter.txt");
            try
            {
                StreamWriter fs = new StreamWriter(file_path, false);
                fs.WriteLine(count);
                fs.Close();
            }
            catch (Exception ex)
            {
                Application["Error"] = ex.Message;
            }
            Application.UnLock(); 
        }

        void Session_End(object sender, EventArgs e) 
        {
            Application.Lock();
            Application["UsersOnline"] = (int)Application["UsersOnline"] - 1;
            Application.UnLock();
        }
           
    </script>
    下面是我的测试页面 WebCount.aspx,简单地在页面上加两个lable显示人数即可:
    using System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;

    public partial class WebCount : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                if (Application["UsersOnline"] != null)
                {
                    //获取当前在线人数
                    currentUserNum.Text = Application["UsersOnline"].ToString();
                }
                if (Application["TotalCount"] != null)
                {
                    //获取网站总访问人数
                    totalUserNum.Text = Application["TotalCount"].ToString();
                }
            }
        }
    }

        具体的有关会话管理的知识可以查看帮助,这里仅就一个问题和大家讨论,路过者有熟悉的请留言或加QQ:65127444
    程序里之所以都使用了 Application ,而没有使用 Session,是因为我使用 <ASP.NET 网络数据库开发实例精解> 一书中第10章的模块 时调试未成功 :(
        下面的代码是这本书中使用 Session 的,可我经过调试,即使多用户同时访问,也还是显示当前在线为1。
    它的实现方式是:将以下代码写在 Session_Start 中,然后在 Session_End 中再减1。
       if(Session["CurrentCount"] != null)
       {
        Session["CurrentCount"] = Int32.Parse(Session["CurrentCount"].ToString()) + 1;
       }
       else
       {
        Session["CurrentCount"] = 1;
       }
        然后将 Page_Load 中显示当前人数的Application["UsersOnline"].ToString() 改为 Session["CurrentCount"].ToString(),不管几个用户同时访问,每个人的浏览器显示的当前人数均为 1。
        呵呵,总结到这里,忽然醒悟了,看来总结也是好处不少啊,呵呵,先说说我写到这里时的理解吧:对象 Session 仅被单个用户所共享,所以,每个用户登录时,Session["CurrentCount"] 都为空,所以,都被赋值为1了,似乎这也充分说明了一些写计算机书籍的人的不负责任,呵呵,随便凑合能看就出版了,代码正确率很低啊!至少,我测试得到的不是想要的结果,也许,我个人的理解有偏差?高手路过的请指点一下了!
        当然,利用读写文件的方式,还可以统计最大在线人数。就是将Application["UsersOnline"]的值和用于保存最大在线人数的文件(如:maxcount.txt)中的值比较,大于则重写,小于则不改变即可。有兴趣的可以自己实现一下,呵呵,好累!
        继续努力了一下,呵呵,最大在线人数的也有了:
            //最大在线人数
            DataSet objDataSet = new DataSet(); 
            objDataSet.ReadXml(Server.MapPath("count.xml"));
            int maxCount = Convert.ToInt32(objDataSet.Tables["MyCount"].Rows[0]["MaxCount"]);
            Application["MaxCount"] = maxCount;
            if (maxCount < (int)Application["UsersOnline"])    //如果MaxCount标签里面的值小于当前在线人数的值,就存入
                objDataSet.Tables["MyCount"].Rows[0]["MaxCount"] = (int)Application["UsersOnline"]; 
                objDataSet.WriteXml(Server.MapPath("count.xml")); 
    附:count.xml:
    <?xml version="1.0" standalone="yes"?>
    <MyCount>
      <MaxCount>0</MaxCount>
    </MyCount>

  • 相关阅读:
    vscode配置备份
    正则替换html代码中img标签的src值
    使用css3原生变量实现主题换肤
    vue3基础知识学习系列(二)响应式原理实现
    vue3基础知识学习系列(一)api使用
    eslint规则中文解释
    开发笔记:使用canvas实现3D金字塔比例图表&#128200;
    实用网页UI调试技巧
    2020年特殊的一年,成就特殊的我们
    java设计模式之责任链模式
  • 原文地址:https://www.cnblogs.com/grj001/p/12224268.html
Copyright © 2011-2022 走看看