asp.net 访问页面访问统计实现
0x00、背景:
1、用户访问网站所有页面就将访问统计数加1 ,按每月存放。
2、站点并没有用到母版面来实现,所有各个页面都很独立。
3、网站是很早这前的网站,尽量省改动以前的代码。按理说我们应该做一个第三方统计来处理会更好,
但应客户要求还要弄到一个站点下!实际情况是尽量小改页面就好!
4、IIs7的服务器请参考 《asp.net 访问页面访问统计实现 for iis7》
0x01、核心代码:
1、实现Http拦截操作,核心代码就是这一个了:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml; namespace HYSWare.Web
{
public class CurVisitCount {
public DateTime BeginTime{get;set;}
public int Count { get; set; }
} public class RequestHandler : IHttpModule
{
private static System.Timers.Timer timer1;
private static System.Web.Caching.Cache _Cache;
private int _IntervalMinute; public int IntervalMinute
{
get
{
string _IntervalMinuteStr = ConfigurationManager.AppSettings["IntervalMinute"]; if (string.IsNullOrEmpty(_IntervalMinuteStr))
{
_IntervalMinute = ;
}
else
{
_IntervalMinute = Convert.ToInt32(_IntervalMinuteStr);
} return _IntervalMinute;
}
} public RequestHandler()
{
if (_Cache == null)
{
_Cache = new System.Web.Caching.Cache();
}
if (timer1 == null)
{
timer1 = new System.Timers.Timer(); timer1.Interval = IntervalMinute * ;
timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Tick);
timer1.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
timer1.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件;
}
if(_Cache["CurVisitCount"]==null)
_Cache["CurVisitCount"] = new CurVisitCount { BeginTime = DateTime.Now, Count = };
if(_Cache["VisitCount"]==null)
_Cache["VisitCount"] = "";
} void IHttpModule.Dispose()
{
} void IHttpModule.Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
//context.EndRequest += new EventHandler(context_EndRequest);
} void context_BeginRequest(object sender, EventArgs e)
{
string[] requestEx = { ".aspx",".htm", ".html"}; HttpApplication application = (HttpApplication)sender;
var curRequest = application.Context.Request;
if (requestEx.Contains(curRequest.CurrentExecutionFilePathExtension)) {
if (_Cache["CurVisitCount"] == null)
_Cache["CurVisitCount"]=new CurVisitCount { BeginTime = DateTime.Now, Count = };
CurVisitCount curVisitCount = (CurVisitCount)_Cache["CurVisitCount"];
if (curVisitCount.BeginTime.Year + curVisitCount.BeginTime.Month < DateTime.Now.Year + DateTime.Now.Month)
{
UpdateVisitCount(curVisitCount.BeginTime);
curVisitCount = (CurVisitCount)_Cache["CurVisitCount"];
}
curVisitCount.Count += ;
_Cache["CurVisitCount"] = curVisitCount; if (_Cache["VisitCountXml"] == null)
_Cache["VisitCountXml"] = GetVisitCountInXml();
int visitCountXml = ;
int.TryParse(_Cache["VisitCountXml"].ToString(),out visitCountXml); _Cache["VisitCount"] = (visitCountXml + curVisitCount.Count).ToString(); }
//application.Context.Response.Write("自定义ModuleRequest开始");
} private int GetVisitCountInXml()
{
int ret = ;
string _VisitPath = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\Xml\\VisitCountData.xml";
XmlDocument doc = new XmlDocument();
if (File.Exists(_VisitPath))
{
doc.Load(_VisitPath);
var curNode = doc.SelectNodes("//Visit");
foreach (XmlNode m in curNode) {
var countAttr = m.Attributes.GetNamedItem("VCount");
int v = ;
int.TryParse(countAttr.Value, out v);
ret += v;
}
}
return ret;
} private void UpdateVisitCount(DateTime time)
{
if (_Cache["CurVisitCount"] == null)
_Cache["CurVisitCount"]= new CurVisitCount { BeginTime = DateTime.Now, Count = };
CurVisitCount curVisitCount = (CurVisitCount)_Cache["CurVisitCount"];
if (curVisitCount.Count > )
{
string _VisitPath = AppDomain.CurrentDomain.BaseDirectory + "App_Data\\Xml\\VisitCountData.xml";
XmlDocument doc = new XmlDocument(); if (File.Exists(_VisitPath))
{
doc.Load(_VisitPath);
var curNode = doc.SelectSingleNode(string.Format("//Visit[@Year='{0}' and @Month='{1}']", time.Year, time.Month));
if (curNode != null)
{
var countAttr = curNode.Attributes.GetNamedItem("VCount");
int count = ;
int.TryParse(countAttr.Value, out count);
countAttr.Value = (count + curVisitCount.Count).ToString();
}
else
{
//有文件但没有本月数据
XmlNode root = doc.SelectSingleNode("Visits");
XmlElement element1 = doc.CreateElement("Visit");
element1.SetAttribute("Year", time.Year.ToString());
element1.SetAttribute("Month", time.Month.ToString());
element1.SetAttribute("VCount", curVisitCount.Count.ToString());
root.AppendChild(element1);
}
}
else
{
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", "utf-8", null);
doc.AppendChild(dec); //创建一个根节点(一级)
XmlElement root = doc.CreateElement("Visits");
doc.AppendChild(root);
//创建节点(二级)
XmlElement element1 = doc.CreateElement("Visit");
element1.SetAttribute("Year", time.Year.ToString());
element1.SetAttribute("Month", time.Month.ToString());
element1.SetAttribute("VCount", curVisitCount.ToString());
root.AppendChild(element1);
}
doc.Save(_VisitPath); _Cache["VisitCountXml"] = GetVisitCountInXml();
_Cache["VisitCount"] = _Cache["VisitCountXml"];
_Cache["CurVisitCount"] = new CurVisitCount { BeginTime = DateTime.Now, Count = };
}
} private void timer1_Tick(object sender, EventArgs e)
{
UpdateVisitCount(DateTime.Now);
}
}
}
2、web.config中添加配置
<!--
有关如何配置 ASP.NET 应用程序的详细信息,请访问
http://go.microsoft.com/fwlink/?LinkId=169433
--> <configuration>
<appSettings>
......
<!--设置更新访问统计Xml,间隔时间(分钟)默认为5分钟-->
<add key="IntervalMinute" value="5"/>
</appSettings>
.......
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add name="customerModule" type="HYSWare.Web.RequestHandler, HYSWare.Web"/>
</modules>
......
</system.webServer>
</configuration>
3、存放数据的XML文件
<?xml version="1.0" encoding="utf-8"?>
<Visits>
<Visit Year="2017" Month="8" VCount="92" />
<Visit Year="2017" Month="7" VCount="13000000" />
</Visits>
4、取得缓存的的访问数据 VisitCountHandler.ashx,VisitCountHandler.ashxcs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace HYSWare.Web
{
/// <summary>
/// VisitCountHandler 的摘要说明
/// </summary>
public class VisitCountHandler : IHttpHandler
{
private static System.Web.Caching.Cache _Cache; public VisitCountHandler() {
if (_Cache == null)
{
_Cache = new System.Web.Caching.Cache();
}
} public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
if (_Cache["VisitCount"] == null)
_Cache["VisitCount"] = "";
context.Response.Write(_Cache["VisitCount"].ToString());
} public bool IsReusable
{
get
{
return false;
}
}
}
}
5、调用取访问统计数据的有js代码
var visitCount = 0;
$.ajax({
type: "Post",
url: "VisitCountHandler.ashx",
data: "{}",
async: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
visitCount = data;
},
error: function (err) {
alert(err);
}
});
0x02、总结:
主要还是觉得缓存使用感觉有点不对的样子,也许有更好的方法!
还有觉得拦截方法也是挻好用的!
asp.net 访问页面访问统计实现的更多相关文章
- asp.net 访问页面访问统计实现 for iis7
上一篇博文中< asp.net 访问页面访问统计实现 > 中在win10 (iis8+)上运行没有问题, 但客户机子是windows server 2008 的 iis7弄死不对,最好 ...
- ASP.NET 数据库页面访问简单工具
在工作中,有很多项目已上线后,很多项目的数据库服务器都不会对外开放的,外网想直接访问客户数据库服务器时,可能会出现困难. 这时就需要一个可以查询,更新数据库操作的页面了: 本来用sql语句直接操作数据 ...
- ASP.net中网站访问量统计方法代码(在线人数,本月访问,本日访问,访问流量,累计访问)
一.建立一个数据表IPStat用于存放用户信息 我在IPStat表中存放的用户信息只包括登录用户的IP(IP_Address),IP来源(IP_Src)和登录时间 (IP_DateTime),些表的信 ...
- 友盟(Swift)-集成、统计用户数量、具体页面访问数量、具体按钮点击数量
什么是友盟.有什么用? 这些傻瓜问题这里就不解释了,可以自己百度去. 友盟提供的文档和demo都是oc的,这里用swift写了一个小demo,在此分享一下. 步骤1:友盟后台注册应用(iOS),拿到a ...
- 使用MySQL统计页面访问及排名
统计访问页面数量,以分辨率进行排名 SELECT CONCAT(`height` , '*', `width`) AS `resolution` , COUNT(CONCAT(`height`, '* ...
- asp dotnet core 通过图片统计 csdn 用户访问
在 csdn 的访问统计里面,只能用 csdn 提供的访问统计,因为在 csdn 中不支持在博客加上 js 代码,也就是无法使用友盟等工具统计. 通过在 asp dotnet core 创建一个图片链 ...
- Asp.net有关访问页面权限的限制和错误页面配置
一.访问页面权限的限制 一个小项目,涉及到用户登录. 在用户没登录访问内容也时,对页面做一定限制,没登录的则不能访问,直接跳转到登录界面. /// <summary> /// 对没有登录用 ...
- Asp.net 页面访问模板页的属性
首先 页面需要添加下面一段代码 <%@ MasterType VirtualPath="~/User/User.Master" %> 添加的位置如图 这样就可以在这个页 ...
- 在Asp.net MVC中访问静态页面
有时候由于一些特殊的需要,我们需要在MVC中访问HTML页面,假如您将这个页面放在Views中的话,去访问将会收到一个404,但是放在Views外面的目录则不受此限制. 那么我们就来解决View里面的 ...
随机推荐
- Spring MVC报异常:org.springframework.web.util.NestedServletException: Request processing failed
在使用SpringMVC绑定基本类型(如String,Integer等)参数时,应通过@RequestParam注解指定具体的参数名称,否则,当源代码在非debug模式下编译后,运行时会引发Handl ...
- 阿里云Logtail 快速诊断工具
当日志采集发生异常时,您可以通过Logtail自助检测工具查看客户端是否存在异常情况,根据工具提示快速定位并解决问题. 说明 本工具目前仅支持Linux系统的服务器. 准备工作 下载检测工具脚本. ...
- 谈谈MySQL死锁 一
数据越来越和我们的生活离不开,数据在生命周期的各个阶段有着不同的痛点和需求以及特殊场景. CURD是数据的四大基本需求:写入,更新,读取,删除. 今天,来谈一谈死锁问题 死锁是高并发下MySQL不可回 ...
- [转]oracle 常用的指令
1.显示当前用户名 select user from dual; show user 2.显示当然用户有哪些表 select * from tab; 3.显示当所有用户的表 select * from ...
- Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name
启动apache的时候,报告以下消息提示: Starting httpd: httpd: Could not reliably determine the server's fully qualifi ...
- MySQL设置全局sql日志
分别执行开启日志以及日志路径和日志文件名 SET GLOBAL general_log_file = '/var/lib/mysql/localhost.log';SET GLOBAL genera ...
- 译: 3. RabbitMQ Spring AMQP 之 Publish/Subscribe 发布和订阅
在第一篇教程中,我们展示了如何使用start.spring.io来利用Spring Initializr创建一个具有RabbitMQ starter dependency的项目来创建spring-am ...
- python 函数的参数的几种类型
定义函数的时候,我们把参数的名字和位置确定下来,函数的接口定义就完成了.对于函数的调用者来说,只需要知道如何传递正确的参数,以及函数将返回什么样的值就够了,函数内部的复杂逻辑被封装起来,调用者无需了解 ...
- Roller5.0.3安装配置部署 step by step
一.下载roller 下载地址:http://roller.apache.org/downloads/downloads.html下载下来之后,解压包含两部份doc.webapps 二.准备环境 1. ...
- sql1032n sql6048n db2start启动不了 db2修改hostname
今天下午把虚拟机上的linux的hostanme改掉了 结果启动DB2的时候发生了这样的错误 SQL6048N A communication error occurred during START ...