zoukankan      html  css  js  c++  java
  • 利用HttpModule做流量记录

    原文转载自 http://www.cnblogs.com/putishu/archive/2010/10/04/1842016.html  仅作学习之用

    利用HttpModule做流量记录

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

    原来打算用免费的流量统计系统,但是考虑到分析数据最好自己保留,所以最终决定自己做。首要一步就是记录流量信息。
    前面《利用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.csModule模块)——————————————————————————————————————————————

    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)
            {
                //
    这里829有更改,这个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"/>




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

  • 相关阅读:
    2010年8月26日周四_understanding ArcGIS Server_overview_8.1
    2010年8月23日周一_FeatureLayer_6.13
    2010年8月22日周日_StylingAndSkinningScaleBar_6.12
    2010年8月26日周四_underStanding Flex_FlexComponets_7.4
    Flex组件的项目渲染器(ItemRenderer)使用总结
    2010年8月26日周四_understanding Flex_componentsLifeCycle_7.5
    2010年8月26日周四_understanding Flex_MXML and ActionScript_7.2
    缺页中断
    后缀式
    lua continue
  • 原文地址:https://www.cnblogs.com/wftrustself/p/3297868.html
Copyright © 2011-2022 走看看