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>

  • 相关阅读:
    hdu 5723 Abandoned country 最小生成树 期望
    OpenJ_POJ C16G Challenge Your Template 迪杰斯特拉
    OpenJ_POJ C16D Extracurricular Sports 打表找规律
    OpenJ_POJ C16B Robot Game 打表找规律
    CCCC 成都信息工程大学游记
    UVALive 6893 The Big Painting hash
    UVALive 6889 City Park 并查集
    UVALive 6888 Ricochet Robots bfs
    UVALive 6886 Golf Bot FFT
    UVALive 6885 Flowery Trails 最短路
  • 原文地址:https://www.cnblogs.com/grj001/p/12224267.html
Copyright © 2011-2022 走看看