65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.41/5 (16投票s)

2002年7月5日

7分钟阅读

viewsIcon

203075

downloadIcon

4835

一个易于在纯 HTML 中使用的 ASP.NET 计数器

引言

有时,将网站页面访问次数显示为页面内容一部分的计数器会很有用。虽然在用 ASP 或 ASP.NET 编写的页面中添加计数器相对简单,但在纯 HTML 页面(没有任何脚本)中添加计数器则略有不同。

本文介绍了我使用 ASP.NET 创建的一个计数器(见下图)。ASP.NET 代码使用 GraphicsBitmap 类生成图像,使其易于在没有客户端脚本的纯 HTML 页面上使用。该代码还维护自己的小型“数据库”,这样您就不必通过 FTP 访问您的 Web 服务器来创建新的计数器。我为我的 eBay 列表和各种其他页面使用并设计了这个计数器;因此,它旨在提高速度,所以它不使用数据库或 XML(但可以很容易地升级以实现此功能)。

Sample Counter

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>

管理计数器数据

计数器使用它通过 FileFileStreamStreamReaderStreamWriter 类访问的简单文本文件来跟踪计数器的值。每个文件包含单个计数器的值,从而在计数器及其数据文件之间创建一对一的关系,使计数器读取和更新快速。以下列表显示了计数器如何为不存在的计数器创建新文件

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 方法更新它——简单快捷。

渲染计数器

如果计数器显示为简单的文本字符串,那它就不会那么有趣了,因此代码使用 BitmapGraphics 类创建图像的内存表示,然后将其直接流式传输到客户端;因此,计数器看起来像一个图像,尽管它只是通过 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);

徽标文本很容易添加到位图,因为其内容不会更改。计数器的值确实会更改,因此您需要更加注意如何将其定位在封闭矩形中。如前一个列表所示,代码使用 FontSolidBursh 对象,如下所示

  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 编程语言,并包含徽标、自动创建新计数器以及阻止用户人为夸大计数器值等功能。

安装和使用示例代码

请按照以下步骤安装示例

  1. 下载代码。
  2. 将代码解压到系统上的一个文件夹中。
  3. 使用 IIS 管理工具或文件夹属性创建一个新的虚拟目录。
  4. 在新虚拟目录下创建一个名为 data 的文件夹。
  5. 授予 IIS 用户账户读取、修改和写入权限。
  6. 将浏览器指向新的虚拟目录。

您应该会看到一个包含简短消息和计数器图像的页面。

© . All rights reserved.