使用 ASP.NET 和 JScript .NET 的页面点击计数器






4.41/5 (16投票s)
2002年7月5日
7分钟阅读

203075

4835
一个易于在纯 HTML 中使用的 ASP.NET 计数器
- 下载源代码文件 - 2 Kb(2004年4月更新)
引言
有时,将网站页面访问次数显示为页面内容一部分的计数器会很有用。虽然在用 ASP 或 ASP.NET 编写的页面中添加计数器相对简单,但在纯 HTML 页面(没有任何脚本)中添加计数器则略有不同。
本文介绍了我使用 ASP.NET 创建的一个计数器(见下图)。ASP.NET 代码使用 Graphics
和 Bitmap
类生成图像,使其易于在没有客户端脚本的纯 HTML 页面上使用。该代码还维护自己的小型“数据库”,这样您就不必通过 FTP 访问您的 Web 服务器来创建新的计数器。我为我的 eBay 列表和各种其他页面使用并设计了这个计数器;因此,它旨在提高速度,所以它不使用数据库或 XML(但可以很容易地升级以实现此功能)。
JScript .NET 概述
JScript .NET 是 .NET Framework 上可用的编程语言之一,是 Microsoft 版本的 ECMAScript——构成 JavaScript 基础的语言。JScript .NET 在许多方面与 C# 和 C++ 非常相似,因此如果您了解其中任何一种语言,您将立即熟悉 JScript .NET。
JScript .NET 是一种面向对象的语言,支持类、继承、多态性以及所有其他流行的面向对象特性。您还可以使用 JScript .NET 创建基于 Windows 窗体的应用程序(具有 GUI 的应用程序)、Windows 服务、控制台应用程序、Web 服务以及 ASP.NET 页面和应用程序。
使用计数器
以下列表演示了如何在纯 HTML 中轻松使用计数器
<img src="EWCounter.aspx?item=CodeProjectArticle">
HTML img
标签的 src
属性指向一个 ASP.NET 页面,该页面处理从文件检索计数器当前值、更新计数器以及返回包含计数器值等信息的图像的详细信息。您可以向图像添加链接,使计数器可点击,如以下列表所示
<a href="http://www.designs2solutions.com" target="_blank"> <img src="EWCounter.aspx?item=CodeProjectArticle" border="0"> </a>
管理计数器数据
计数器使用它通过 File
、FileStream
、StreamReader
和 StreamWriter
类访问的简单文本文件来跟踪计数器的值。每个文件包含单个计数器的值,从而在计数器及其数据文件之间创建一对一的关系,使计数器读取和更新快速。以下列表显示了计数器如何为不存在的计数器创建新文件
var itm :String = Request.QueryString("item");
// ... elsewhere on the page ...
createCounter(itm);
// etc...
function createCounter(nameOfItem:String)
{
var sw : StreamWriter;
var filePath:String = Server.MapPath("data\\") + nameOfItem + ".txt";
if(!File.Exists(filePath)) {
sw=File.CreateText(filePath);
sw.WriteLine("99");
sw.Close();
}
}
计数器的初始值为 99,使其看起来像页面的第一个访问者是第一百个访问者(必须乐观)。要创建新的计数器,请为 QueryString 上的 item
指定一个新的、唯一的值,如前面的 HTML 代码所示。
检索并可选更新计数器值的代码很简单。该代码不执行文件中的任何随机访问,只是使用 StreamReader
读取值并可选使用 StreamWriter
写入更新后的值,如以下列表所示
function getCounterValue(nameOfItem : String, readOnly : Boolean) : String
{
var fileIn:StreamReader =
File.OpenText(Server.MapPath("data\\" + nameOfItem + ".txt"),
FileMode.Open);
var current : String = new String("");
current = fileIn.ReadLine().ToString();
fileIn.Close();
if(readOnly)
return current;
var curInt : int = Convert.ToInt32(current);
curInt++;
var fs : FileStream =
new FileStream(Server.MapPath("data\\" + nameOfItem + ".txt"),
FileMode.Open,FileAccess.Write);
var sw : StreamWriter;
sw = new StreamWriter(fs);
sw.WriteLine(Convert.ToString(curInt));
sw.Close();
fs.Close();
return Convert.ToString(curInt);
}
代码使用 StreamReader.ReadLine
方法读取计数器的当前值,并可选使用 StreamReader.WriteLine
方法更新它——简单快捷。
渲染计数器
如果计数器显示为简单的文本字符串,那它就不会那么有趣了,因此代码使用 Bitmap
和 Graphics
类创建图像的内存表示,然后将其直接流式传输到客户端;因此,计数器看起来像一个图像,尽管它只是通过 Response 对象发送到客户端的位流。
代码做的第一件事是创建一个 Bitmap
对象,该对象流式传输到客户端并使用 Graphics
对象进行操作,如以下列表所示
function drawCounter(nameOfItem : String, readOnly : Boolean)
{
// some code omitted for brevity...
var height : int = 20;
var width : int = 100;
var bmp : Bitmap= new Bitmap(width, height);
var g:Graphics = Graphics.FromImage(bmp);
// Create a DarkBlue background
g.FillRectangle(new SolidBrush(Color.DarkBlue), 0, 0, width, height);
// LightGreen for the small box on the left...
g.FillRectangle(new SolidBrush(Color.LightGreen), 0, 0, 26, 20);
前面的列表建立了它需要使用的两个对象,并创建了显示计数器值的深蓝色框,以及计数器左侧用于容纳计数器标志的浅绿色框。
计数器的标志由三个字符组成:“D2S”。您可以使用 Graphics.DrawString
方法向位图添加文本。但是,在执行此操作之前,您需要确定用于绘制文本的颜色和文本的字体,最后需要做的是将文本定位在框内,如以下列表所示
var maroonBrush:SolidBrush= new SolidBrush(Color.Maroon);
var blackBrush:SolidBrush= new SolidBrush(Color.Black);
var counterByFont:Font = new Font("Verdana", 7, FontStyle.Bold);
g.DrawString("D", counterByFont,blackBrush ,0,5);
g.DrawString("2", counterByFont,maroonBrush ,8,2);
g.DrawString("S", counterByFont,blackBrush ,16,5);
徽标文本很容易添加到位图,因为其内容不会更改。计数器的值确实会更改,因此您需要更加注意如何将其定位在封闭矩形中。如前一个列表所示,代码使用 Font
和 SolidBursh
对象,如下所示
var counterFont:Font = new Font("Verdana", 8, FontStyle.Bold);
var whiteBrush:SolidBrush= new SolidBrush(Color.White);
当您在位图上定位某个对象时,您通过定义您要绘制的对象的顶部、左侧像素来确定其位置。由于计数器的长度可以变化(随着计数器值的增加),因此代码测量计数器值在封闭框中显示的长度,并将其定位,以便所有数字都可见,如以下列表所示
var counterText : SizeF;
counterText = g.MeasureString(counterValue,counterFont);
g.DrawString(counterValue, counterFont, whiteBrush ,
(bmp.Width)-((counterText.Width)+5),3);
这段简短的代码做了很多事情:它首先使用 Graphics.MeasureString
方法和 SizeF
对象,根据将要渲染的字体测量计数器的值。然后代码使用 Graphics.DrawString
渲染字符串,并将文本定位在距离封闭框边缘 3 像素的位置。
当计数器准备好呈现时,代码做的最后一件事是使用以下行将其以 JPG 图像的形式交付给客户端
bmp.Save(Response.OutputStream, ImageFormat.Jpeg);
限制计数器更新
到目前为止您看到的代码在更新计数器时不是很挑剔:当用户刷新页面时,计数器会更新。虽然这在大多数情况下是可以的,但在某些情况下,您希望确保用户不会每隔几秒钟就刷新页面以“操纵”计数器的值(通过人为地夸大值导致访问者数量失真)。
解决此问题的一种方法是使用在设定时间段后过期的 cookie。如果 cookie 未过期,则计数器的值不会更新,但仍会显示。在 ASP.NET 中使用 cookie 相对简单,只要您意识到已过期的 cookie 等同于 null
/ 不存在的 cookie。以下列表显示了管理 cookie 并设置 readOnly
值的代码,该值决定计数器是更新还是仅显示
var cookie:HttpCookie;
cookie = Request.Cookies("LastVisit");
var readOnly:Boolean = (cookie!=null);
drawCounter(itm,readOnly);
if(!readOnly) {
cookie = new HttpCookie("LastVisit",DateTime.Now.AddSeconds(120));
cookie.Expires = DateTime.Now.AddSeconds(60);
Response.AppendCookie(cookie);
}
代码查询一个名为“LastVisit”的 cookie——如果该 cookie 不存在或已过期,则为 null
。在显示和更新计数器(取决于 readOnly
的值)之后,代码再次评估 readOnly
以生成一个新的 cookie,以防这是用户首次访问或 cookie 已过期。在这种情况下,代码将 cookie 设置为两分钟后过期。请注意,此解决方案可能并非在所有情况下都有效,具体取决于用户的浏览器安全设置(用户可以将其浏览器配置为拒绝来自第三方网站的 cookie);但是,此解决方案可能会阻止大多数用户“操纵”计数器值。
摘要
本文介绍了如何创建一个快速的页面点击计数器,该计数器易于与纯 HTML 配合使用。该代码使用 ASP.NET 和 JScript .NET 编程语言,并包含徽标、自动创建新计数器以及阻止用户人为夸大计数器值等功能。
安装和使用示例代码
请按照以下步骤安装示例
- 下载代码。
- 将代码解压到系统上的一个文件夹中。
- 使用 IIS 管理工具或文件夹属性创建一个新的虚拟目录。
- 在新虚拟目录下创建一个名为 data 的文件夹。
- 授予 IIS 用户账户读取、修改和写入权限。
- 将浏览器指向新的虚拟目录。
您应该会看到一个包含简短消息和计数器图像的页面。