【问题标题】:Creating hit counter for website为网站创建点击计数器
【发布时间】:2013-07-12 21:48:50
【问题描述】:

我正在创建一个具有母版页的网站。我想创建一个计数器来记录访问者的数量,我找到了一个代码并将其放在我的母版页中。代码如下: 标记代码:

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="counter.ascx.cs" Inherits="counter" %>
<asp:Label ID="lblCounter" runat="server"></asp:Label>

代码隐藏 - C#:

protected void Page_Load(object sender, EventArgs e)
{
 this.countMe();
 DataSet tmpDs = new DataSet();
 tmpDs.ReadXml(Server.MapPath("~/counter.xml"));
 lblCounter.Text = tmpDs.Tables[0].Rows[0]["hits"].ToString();
}
private void countMe()
{
 DataSet tmpDs = new DataSet();
 tmpDs.ReadXml(Server.MapPath("~/counter.xml"));
 int hits = Int32.Parse(tmpDs.Tables[0].Rows[0]["hits"].ToString());
 hits += 1;
 tmpDs.Tables[0].Rows[0]["hits"] = hits.ToString();
 tmpDs.WriteXml(Server.MapPath("~/counter.xml"));
}

根目录中的一个 xml 文件,用于使代码工作。 XML文件如下:

 <?xml version="1.0" encoding="utf-8" ?>
 <counter>
   <count>
      <hits>0</hits>
   </count>
 </counter>

但我网站中的每个页面都会在我访问它们时触发计数器。请帮我修改这段代码,让一位访客只触发一次计数器。

我决定只将代码放在索引页面上,但每次刷新和每次打开索引的舔(即使停留在索引页面上)都会触发计数器。

【问题讨论】:

  • 当然,如果两个访问者同时运行countMe 方法,您很可能会 a) 如果 I/O 发生在错误的时间和/或者您最终只会计算一次访问(两者都读取计数 73,都向其添加 1,都保存更新后的 XML,计数为 74)。您存储在 XML 文件中的任何原因?

标签: c# asp.net


【解决方案1】:

为什么不只添加一个会话?我认为这是 XML 解决方案最简单的方法,如果您将其保存到 SQL 中,您可能会涉及更多逻辑。

private void countMe()
{
 if(Session["Counted"]==null){
 DataSet tmpDs = new DataSet();
 tmpDs.ReadXml(Server.MapPath("~/counter.xml"));
 int hits = Int32.Parse(tmpDs.Tables[0].Rows[0]["hits"].ToString());
 hits += 1;
 tmpDs.Tables[0].Rows[0]["hits"] = hits.ToString();
 tmpDs.WriteXml(Server.MapPath("~/counter.xml"));
 Session["Counted"] = "Yes";
}
}

【讨论】:

    【解决方案2】:

    您需要检查页面的 url 以使计数器命中代码。试试这样的

    protected void Page_Load(object sender, EventArgs e)
    {
       string url = HttpContext.Current.Request.Url.AbsoluteUri;
       if(url.Contains("index.aspx")
       {
         this.countMe();
       }
       DataSet tmpDs = new DataSet();
       tmpDs.ReadXml(Server.MapPath("~/counter.xml"));
       lblCounter.Text = tmpDs.Tables[0].Rows[0]["hits"].ToString();
    }
    

    【讨论】:

      【解决方案3】:

      您可以从 Global.ascx 文件中获得解决方案。 转到应用程序中 Golobal.ascx.cs 后面的代码。 在 Global.Cs 文件中声明一个变量。 并在 Global.ascx.cs 文件的 'Session_Start' 函数中维护一个计数; 编写一些公共方法来获取用户数

      例如:

      protected void Session_Start(Object sender, EventArgs e)
      {
        totalNumberOfUsers += 1;
        currentNumberOfUsers += 1;
      }
      
      
      protected void Session_End(Object sender, EventArgs e)
      {
        currentNumberOfUsers -= 1;
      }
      
      public static int TotalNumberOfUsers
      {
        get
        {
          return totalNumberOfUsers;
        }
      }
      
      public static int CurrentNumberOfUsers
      {
        get
        {
          return currentNumberOfUsers;
        }
      } 
      

      【讨论】:

        【解决方案4】:

        除了在prospectors示例中使用“Session”之外,由于可能存在同步问题,请不要忘记在使用前锁定DataSet。

        private static readonly object LockObj = new object();
        private static DataSet dataSet = new DataSet();
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Session["Counted"] == null)
            {
                lock (LockObj)
                {
                    dataSet.ReadXml(Server.MapPath("~/counter.xml"));
                    dataSet.Tables[0].Rows[0]["hits"] = (1 + int.Parse(dataSet.Tables[0].Rows[0]["hits"].ToString())).ToString();
                    dataSet.WriteXml(Server.MapPath("~/counter.xml"));
                    dataset.clear();
                }
                Session["Counted"] = "true";               
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-12-21
          • 1970-01-01
          • 1970-01-01
          • 2018-03-21
          • 2018-07-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多