原创 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生成的脚本类型注册等,引发错误!
尽量捕捉错误,因为这些错误可能不会直接爆出,引发请求中断,让人有的时候摸不着头脑!


 

 

数据分析之数据清洗

一、数据导入 In [144]: #读取数据 import matplotlib.pyplot as plt %matplotlib notebook impo...
  • u013584315
  • u013584315
  • 2018年01月07日 14:07
  • 78

单片机读入4*4矩阵键盘

一、什么是矩阵键盘 矩阵键盘是单片机外部设备中所使用的排布类似于矩阵的键盘组,由于电路设计时需要更多的外部输入,单独的控制一个按键需要浪费很多的IO资源,所以就有了矩阵键盘,常用的矩阵键盘有4*4和...
  • snyanglq
  • snyanglq
  • 2015年12月03日 11:55
  • 5494

什么是4:4:4、4:2:2、4:2:0?了解图像压缩取样的方式

什么是4:4:4、4:2:2、4:2:0?了解图像压缩取样的方式 我们经常会看到4:4:4、4:2:2、4:2:0这样的字眼,比如你的5D拍摄的视频是4:2:0取样压缩的,又比如QuickTime...
  • euyy1029
  • euyy1029
  • 2017年05月18日 10:33
  • 1506

4*4键盘程序代码 基于STM32

4*4键盘程序代码 基于STM32   这是自己写的扫描第一行按键的程序代码。 PE的位8~位11设置为下拉输入。 PE的位12~位15设置为推挽输出 其中PE的位11是4*4键盘的第一列,...
  • xxz1014
  • xxz1014
  • 2014年10月31日 20:13
  • 1503

自学QT之Qt 4迁移至Qt 5

原文地址:http://www.kdab.com/porting-from-qt-4-to-qt-5/ 中文翻译地址:http://blog.qt.io/cn/2012/07/09/porting-...
  • xuancailinggan
  • xuancailinggan
  • 2016年01月01日 16:30
  • 746

初试虚幻4引擎感想

时间 2014-11-06 00:28:12 原文                  http://blog.csdn.net/langresser_king/article/details/4...
  • dj0379
  • dj0379
  • 2016年06月07日 14:25
  • 10699

stm32 4*4矩阵键盘

stm32f030开发板 使用HAL库 代码如下: .h文件 /* * * Name: keypad.h * Faq: www.mazclub.com */ #ifndef KEYPAD_H #d...
  • fengyu09
  • fengyu09
  • 2015年12月23日 11:30
  • 3097

4*4(齐次)矩阵

4*4矩阵一般也叫齐次矩阵,主要有两个作用,描述平移变换,描述透视投影变换 4*4平移矩阵 3*3矩阵可以用来旋转,缩放坐标系,但不能移动坐标系 需要在4维空间切变实现3维平移(比较...
  • OnafioO
  • OnafioO
  • 2016年12月22日 18:15
  • 2454

虚幻4-入门第一课-环境安装

安装虚幻4游戏引擎开发环境博主游戏开发小白一个,打进天起就要开始虚幻4游戏开发的征程啦,特地整理一些容易入手的干货,先挑软柿子捏一捏: 虚幻4开发者账号注册 虚幻4游戏引擎下载 虚幻4的开发者工具介绍...
  • ndscbetter
  • ndscbetter
  • 2016年09月27日 23:58
  • 1825

虚幻4与Unity: 哪个游戏引擎是开发者的最爱?

转自:http://www.narkii.com/club/thread-335184-1.html 虚幻4与Unity: 哪个游戏引擎是开发者的最爱? 虚幻4 (UE4) 和Uni...
  • light_purple
  • light_purple
  • 2015年09月08日 20:23
  • 4854
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:
举报原因:
原因补充:

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