原创 2007年09月13日 21:26:00

简单需求:
记录用户访问网站的地址,浏览器,时间,用户信息等信息。

原来打算用免费的流量统计系统,但是考虑到分析数据最好自己保留,所以最终决定自己做。首要一步就是记录流量信息。
前面《利用HttpModule实现浏览器版本控制》就是在利用HttpModule记录流量信息时做的衍生,同时也可以实现页面编程无需任何附加代码。不需要加JS代码段也不要附加任何CS代码段。并且模块相互独立,可以重复利用,也利于不需要时分离。


FlowEntity.cs(信息实体)——————————————————————————————————————————————
using System;
using System.Collections.Generic;
using System.Text;

namespace Xingmai.WebSite.FlowStatistics
{
    /// <summary>
    /// 流量记录单个记录集
    /// </summary>
    public class FlowEntity
    {
        private FlowAgentEntity _AgentInfo;
        private FlowUserInfoEntity _UserInfo;
        private FlowRequestEntity _RequestInfo;

        /// <summary>
        /// 用户基本信息
        /// </summary>
        public FlowUserInfoEntity UserInfo
        {
            get
            {
                return _UserInfo;
            }
            set
            {
                _UserInfo = value;
            }
        }

        /// <summary>
        /// 用户代理信息
        /// </summary>
        public FlowAgentEntity AgentInfo
        {
            get
            {
                return _AgentInfo;
            }
            set
            {
                _AgentInfo = value;
            }
        }

        /// <summary>
        /// 用户访问信息
        /// </summary>
        public FlowRequestEntity RequestInfo
        {
            get
            {
                return _RequestInfo;
            }
            set
            {
                _RequestInfo = value;
            }
        }
    }

    /// <summary>
    /// 用户基本信息实体
    /// </summary>
    public class FlowUserInfoEntity
    {
        private int _UserID;
        private string _UserName;

        /// <summary>
        /// 用户ID
        /// </summary>
        public int UserID
        {
            get
            {
                return _UserID;
            }
            set
            {
                _UserID = value;
            }
        }

        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName
        {
            get
            {
                return _UserName;
            }
            set
            {
                _UserName = value;
            }
        }
    }

    /// <summary>
    /// 用户代理信息实体
    /// </summary>
    public class FlowAgentEntity
    {
        private int _BrowserMajorVer;
        private double _BrowserMinorVer;
        private string _BrowserName;
        private string _HostName;
        private string _IP;
        private string _Language;
        private string _PlatForm;

        /// <summary>
        /// 用户访问IP
        /// </summary>
        public string IP
        {
            get
            {
                return _IP;
            }
            set
            {
                _IP = value;
            }
        }

        /// <summary>
        /// 用户主机名
        /// </summary>
        public string HostName
        {
            get
            {
                return _HostName;
            }
            set
            {
                _HostName = value;
            }
        }

        /// <summary>
        /// 用户语种
        /// </summary>
        public string Language
        {
            get
            {
                return _Language;
            }
            set
            {
                _Language = value;
            }
        }

        /// <summary>
        /// 用户操作系统平台
        /// </summary>
        public string PlatForm
        {
            get
            {
                return _PlatForm;
            }
            set
            {
                _PlatForm = value;
            }
        }

        /// <summary>
        /// 浏览器名称
        /// </summary>
        public string BrowserName
        {
            get
            {
                return _BrowserName;
            }
            set
            {
                _BrowserName = value;
            }
        }

        /// <summary>
        /// 浏览器主版本号
        /// </summary>
        public int BrowserMajorVer
        {
            get
            {
                return _BrowserMajorVer;
            }
            set
            {
                _BrowserMajorVer = value;
            }
        }

        /// <summary>
        /// 浏览器次版本号
        /// </summary>
        public double BrowserMinorVer
        {
            get
            {
                return _BrowserMinorVer;
            }
            set
            {
                _BrowserMinorVer = value;
            }
        }
    }

    /// <summary>
    /// 用户访问信息实体
    /// </summary>
    public class FlowRequestEntity
    {
        private DateTime _RequestDateTime;
        private string _RequestUrl;

        /// <summary>
        /// 访问时间
        /// </summary>
        public DateTime RequestDateTime
        {
            get
            {
                return _RequestDateTime;
            }
            set
            {
                _RequestDateTime = value;
            }
        }

        /// <summary>
        /// 访问地址
        /// </summary>
        public string RequestUrl
        {
            get
            {
                return _RequestUrl;
            }
            set
            {
                _RequestUrl = value;
            }
        }
    }
}

FlowModule.cs(Module模块)——————————————————————————————————————————————

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Xml;
using System.IO;
using System.Configuration;

namespace Xingmai.WebSite.FlowStatistics
{
    public class FlowModule : IHttpModule
    {
        #region 内部似有变量

        private string[] FlowType;
        private FlowDAL dal;

        #endregion

        #region 内部自有方法

        private bool IsFlowType(string strUrl)
        {
            foreach (string strFlowType in FlowType)
            {
                if (strUrl.ToLower().Contains(strFlowType))
                {
                    return true;
                }
            }
            return false;
        }


        #endregion

        #region 实例构造函数

        public FlowModule()
        {
            //读取记录数据的类型
            try
            {
                FlowType = ConfigurationManager.AppSettings["FlowType"].Split((new string[] { "|" }), StringSplitOptions.RemoveEmptyEntries);
            }
            catch (System.Configuration.ConfigurationErrorsException ex)
            {
                throw new Exception(string.Format("请正确配置web.config AppSetting[BrowserChooserPage]节点,系统错误提示:{0}", ex.Message));
            }
            catch (System.Exception ex)
            {
                throw ex;
            }
            //实例化数据层
            dal = new FlowDAL();
        }

        #endregion

        #region IHttpModule 成员


        public void Init(HttpApplication application)
        {
            
//这里8月29日有更改,这个BeginRequest事件里面无法获取到Session,疏忽,望大家谅解!应改用AcquireRequestState事件!
            //
application.BeginRequest += (new EventHandler(this.Application_BeginRequest));
            application.AcquireRequestState+=new EventHandler(application_AcquireRequestState);
        }

        private void application_AcquireRequestState(Object source, EventArgs e)
        {

            HttpApplication Application = (HttpApplication)source;
            HttpContext ctx = Application.Context;
            
            if(!IsFlowType(ctx.Request.Url.AbsoluteUri))
                 return;


            FlowUserInfoEntity user = new FlowUserInfoEntity();
            if (ctx.Session["UserInfo"] != null)
            {
                user.UserID = 1;
                user.UserName = "ceshi";
            }
            else
            {
                user.UserID = 0;
                user.UserName = "UnKnown";
            }

            FlowRequestEntity request = new FlowRequestEntity();
            request.RequestDateTime = DateTime.Now;
            request.RequestUrl = ctx.Request.Url.AbsoluteUri;

            FlowAgentEntity agent = new FlowAgentEntity();
            agent.BrowserMajorVer = ctx.Request.Browser.MajorVersion;
            agent.BrowserMinorVer = ctx.Request.Browser.MinorVersion;
            agent.BrowserName = ctx.Request.Browser.Browser;
            agent.HostName = ctx.Request.UserHostName;
            agent.IP = ctx.Request.UserHostAddress;
            agent.Language = ctx.Request.UserLanguages[0];
            agent.PlatForm = ctx.Request.Browser.Platform;

            FlowEntity entity = new FlowEntity();
            entity.AgentInfo = agent;
            entity.UserInfo = user;
            entity.RequestInfo = request;
            dal.Record(entity);
        }

        public void Dispose()
        {

        }

        #endregion
    }
}

FlowDAL.cs(数据存储层,可以根据自己的需要重写此层。想存数据库也行,XML也行)—————————————————————————

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Configuration;

namespace Xingmai.WebSite.FlowStatistics
{
    /// <summary>
    /// 流量统计数据层
    /// </summary>
    public class FlowDAL
    {
        private SqlConnection _conn;
   
        public FlowDAL()
        {
            try
            {
                _conn = new SqlConnection(ConfigurationManager.ConnectionStrings["FlowConn"].ConnectionString);
                _conn.Open();
            }
            catch (ConfigurationErrorsException ex)
            {
                throw new Exception(string.Format("请正确配置web.config AppSetting[BrowserChooserPage]节点,系统错误提示:{0}", ex.Message));
            }
            catch (SqlException ex)
            {
                throw ex;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 记录流量信息
        /// </summary>
        /// <param name="flowEntity">流量记录实体</param>
        public void Record(FlowEntity flowEntity)
        {
            //判断连接是否为打开状态
            if (_conn.State = !ConnectionState.Open)
                _conn.Open();

     ///////记录代码略////////
        }

        public void Dispose()
        {
            _conn.Close();
        }
    }
}

web.config <system.web> <httpModules> 配置节点—————————————————————————————————
<add name="FlowModule" type="Xingmai.WebSite.FlowStatistics.FlowModule, Xingmai.WebSite.FlowStatistics"/>

web.config <appSettings> 配置节点 (需要记录的类型)——————————————————————————————
<add key="FlowType" value=".htm|.html|.aspx|.asmx"/>

web.config <connectionStrings>配置节点 (记录数据库的连接,如果你重写的数据层,那么这个可要可不要)——————
<add name="FlowConn" connectionString="" providerName="System.Data.SqlClient"/>




关于IHttpModule(MSDN信息)
自定义 HTTP 模块阐释了 HTTP 模块的基本功能。在响应下面两个事件时调用该模块:BeginRequest 事件和 EndRequest 事件。这使该模块可以在处理页请求之前和之后运行。在这种情况下,

该模块向请求的 ASP.NET 网页的任一 HTTP 请求开头处添加一条消息,并在处理请求后添加另一条消息。

注意
BeginRequest 和 EndRequest 事件只是在处理页期间发生的两个事件。有关在处理页期间引发的事件的更多信息,请参见 ASP.NET 网页中的服务器事件处理。

每个事件处理程序都编写为模块的私有方法。在引发已注册事件时,ASP.NET 调用该模块中适当的处理程序方法,该方法将信息写入 ASP.NET 网页中。

创建自定义 HTTP 模块类
如果网站还没有 App_Code 文件夹,请在该站点的根目录下创建这样的一个文件夹。

在 App_Code 目录中,创建一个名为  HelloWorldModule.cs的类文件。

注意
或者,可以将 HelloWorldModule 类编译到一个库中,并将得到的 .dll 文件放在 Web 应用程序的 Bin 目录中。

将以下代码添加到该类文件中:

C# 
public class HelloWorldModule : IHttpModule
{
    public HelloWorldModule()
    {
    }

    public String ModuleName
    {
        get { return "HelloWorldModule"; }
    }

    // In the Init function, register for HttpApplication
    // events by adding your handlers.
    public void Init(HttpApplication application)
    {
        application.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
        application.EndRequest +=
            (new EventHandler(this.Application_EndRequest));
    }

    private void Application_BeginRequest(Object source,
         EventArgs e)
    {
    // Create HttpApplication and HttpContext objects to access
    // request and response properties.
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<h1><font color=red>
            HelloWorldModule: Beginning of Request
            </font></h1><hr>");
    }

    private void Application_EndRequest(Object source, EventArgs e)
    {
        HttpApplication application = (HttpApplication)source;
        HttpContext context = application.Context;
        context.Response.Write("<hr><h1><font color=red>
            HelloWorldModule: End of Request</font></h1>");
    }

    public void Dispose()
    {
    }
}
 
注册 HTTP 模块
在创建完 HelloWorldModule 类后,可以通过在 Web.config 文件中创建一项来注册该模块。

在 Web.config 文件中注册该模块
如果网站还没有 Web.config 文件,请在该站点的根目录下创建一个这样的文件。

将下面突出显示的代码添加到该 Web.config 文件中:

  复制代码
<configuration>
    <system.web>
        <httpModules>
          <add name="HelloWorldModule" type="HelloWorldModule"/>
        </httpModules>
    </system.web>
</configuration>
 

这段代码用 HelloWorldModule 的类名和模块名注册该模块。

测试自定义 HTTP 模块
创建并注册完自定义 HTTP 模块后,可以对它进行测试。

测试自定义 HTTP 模块
在应用程序中创建一个 Default.aspx 页。

在浏览器中请求该 Default.aspx 页。

HTTP 模块会将一个字符串追加到响应的开头和结尾。在请求扩展名指定为 ASP.NET 类型的文件时,该模块将会自动运行。



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
后续《利用HttpModule做流量记录 补充》对方案进行了一些补充

如果选用从Session中传入用户信息或者其他需要记录的信息,请在记录前加判断(2007年8月29日20:34:43增加)
 if (ctx.Handler is Page || ctx.Handler is WebService)
根据需要选用Page还是WebService。
调试过程中发现,如果是其他的类型可能不创建Session,这时从Session读取数据发生错误,造成整个请求中断引起请求失效。这样其他的Module可能不能执行造成页面上一些需要生成的东西无法生成,例如Asp.net Ajax从WebService生成的脚本类型注册等,引发错误!
尽量捕捉错误,因为这些错误可能不会直接爆出,引发请求中断,让人有的时候摸不着头脑!


 

 
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

2017 Multi-University Training Contest - Team 4:1009&hdu6075、Questionnaire

题目: Questionnaire Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Oth...

UE4引擎学习笔记:Blueprints Visual Scripting->Basic Scripting

前言这几天学习了一下有关UE4蓝图的相关知识,发现其中有一些知识盲区和技巧容易忘记,在此整理一下,方便自己后续查询,也希望给有需要的人带来帮助...

PIXHAWK -- PX4 -- EKF2 调试

by luoshi006

机器学习基石2-4 Non-Separable Data

上一节中从数学角度证明了PLA在Data是处于linear separable的状态下在运行一段时间之后是一定能够停下来的。本节介绍了一种在不确定data是否处于linear separable的状态...

百行代码入门Python - Chapter 4

以下代码均采用Python 3.5.2编写。新建一个名为HelloWorld.py的文件,当然名字无所谓,输入以下代码:

maven笔记4--聚合与继承

前言: maven的聚合特性能把项目的各个模块聚合在一起构建,maven的继承特性则能帮助抽取各个模块相同的依赖和插件等配置,在简化POM的同时还成促进各个模块配置的一致性。 测试类的包名...

UE4 C++实现搜索指定目录下的指定类型的所有文件

实现代码如下 // 遍历文件夹下指定类型文件 // Files 保存遍例到的所有文件 // FilePath 文件夹路径 如 "D:\\MyCodes\\LearnUE4Cpp\\Source\\...

utf8mb4和utf8

来源:JavaRanger - 专注JAVA高性能程序开发、JVM、Mysql优化、算法 一、简介MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的...

OpenCV成长之路(4):图像直方图

一、图像直方图的概念 图像直方图是反映一个图像像素分布的统计表,其实横坐标代表了图像像素的种类,可以是灰度的,也可以是彩色的。纵坐标代表了每一种颜色值在图像中的像素总数或者占所有像素个数的百分比。 ...

4 Python中的异常

Python异常处理,新异常的定义,异常触发,异常类型
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)