asp.net IHttpModule.启动请求触发2次,应用程序启动请求触发1次

d5vmydt9  于 2023-01-03  发布在  .NET
关注(0)|答案(7)|浏览(194)

我正在运行VS 2008和. NET 3.5 SP1。
我想在我的ASP.NET应用程序中的HttpModule中实现点击跟踪。我认为这很简单。但是,我的HttpModuleBeginRequest事件在每次页面点击时触发两次。该站点现在非常简单...没有安全性,只是一些数据库工作。应该记录每次页面点击的一行。为什么这个事件触发两次?
此外,IHttpModule.BeginRequest在第一次运行时(从关闭的Web浏览器),第一次点击页面时实际触发的次数不同...当我点击DB为页面提供动态数据时触发3次,而对于没有点击DB的页面只触发1次。
有趣的是,Application_BeginRequest(在Global.asax中)总是只触发一次。
下面是代码:

using System;
using System.Data;
using System.Data.Common;
using System.Net;
using System.Web;
using BluHeron.BusinessLayer;
using Microsoft.Practices.EnterpriseLibrary.Data.Sql;

namespace BluHeron.HttpModules
{
    public class SiteUsageModule : IHttpModule
    {
        public void Init(HttpApplication httpApp)
        {
            httpApp.BeginRequest += OnBeginRequest;
        }

        static void OnBeginRequest(object sender, EventArgs a)
        {
            UsageLogger.LogSiteUsage(((HttpApplication)sender).Context.Request);
        }

        public void Dispose()
        { }
    }

    public static class UsageLogger
    {
        public static void LogSiteUsage(HttpRequest r)
        {
            string ipAddress = GetHostAddress(Dns.GetHostAddresses(Dns.GetHostName()));
            string browserVersion = r.Browser.Type;

            string[] urlChunks = r.RawUrl.Split('/');
            string page = urlChunks[urlChunks.GetLength(0)-1];

            SqlDatabase db = new SqlDatabase(Common.GetConnectionString());
            DbCommand cmd = db.GetStoredProcCommand("LogUsage");

            db.AddInParameter(cmd, "IPAddress", SqlDbType.NVarChar, ipAddress);
            db.AddInParameter(cmd, "BrowserVersion", SqlDbType.NVarChar, browserVersion);
            db.AddInParameter(cmd, "PageName", SqlDbType.NVarChar, page);
            db.AddInParameter(cmd, "Notes", SqlDbType.NVarChar, "");

            db.ExecuteNonQuery(cmd);
        }

        private static string GetHostAddress(IPAddress[] addresses)
        {
            foreach (IPAddress ip in addresses)
            {
                if (ip.ToString().Length <= 15)
                {
                    return ip.ToString();
                }
            }

            return "";
        }
    }
}
plicqrtu

plicqrtu1#

这可能是为时已晚的答案,但可能对其他人有用。我面临着同样的问题。BeginRequest事件触发两次,为每个请求。我调试代码,并意识到,第一次触发实际资源请求,但第二次是“favicon.ico”请求的结果。在BeginRequest事件开始时,一个简单的检查favicon.ico请求消除第二次执行的方法。

public void Application_BeginRequest(object sender, EventArgs e) {
   HttpApplication app = (HttpApplication)sender;
   HttpContext ctx = app.Context;

   if (ctx.Request.Path == "/favicon.ico") { return; }
flmtquvp

flmtquvp2#

在这方面很晚了,但遇到了同样的问题。在我们的例子中,这是由于匿名请求第一次返回401每个RFC。第二次请求认证。

bqf10yzr

bqf10yzr3#

IIS的“默认文档”部分似乎触发了第二个BeginRequest事件。
如果已确定两个事件处理程序中的Request.PathHttpApplication相同,并且URL以斜杠结尾,请尝试添加URL重写规则以简化“默认文档”处理。

qxgroojn

qxgroojn4#

这很有趣。我从母版页中删除了对CSS文件的引用,在HttpModule中,对于某些浏览器,我得到了更少的重复点击(正如建议的那样),但我仍然得到了重复点击。我安装了6个浏览器,我得到了它们之间的一些变化。
作为参考,这是我插入浏览器进行测试的URL:

http://localhost/BluHeron
  • default.aspx* 被设置为起始页,并且确实为前面提到的URL返回。我使用HttpRequest.RawUrl报告用户点击了哪个页面。具体来说,我拆分RawUrl字符串,只报告字符串数组中的最后一项(见代码)。
  • 每个浏览器都报告点击了 default.aspx,正如预期的那样(RawUrl = /BluHeron/default.aspx)。
  • 6个浏览器中有4个还报告了BluHeron(RawUrl = /BluHeron)。
  • 6个浏览器中有3个还在数据库中记录空白(RawUrl = /BluHeron/)。

有几种方法可以准确地报告有多少人点击了哪些页面。
1.从数据库中只选择实际列出我的一个页面的行(忽略/BluHeron和空白)
1.只需在 global.asax 文件中使用Application_BeginRequest,每次页面命中似乎总是只调用一次。
1.把这事弄清楚。
所以,即使数据库中的数据很糟糕,我也可以选择获得好的报告。我更喜欢了解这里发生了什么,而不是数据库中有垃圾。
感谢大家的收看!

p4tfgftt

p4tfgftt5#

我们通过使用

HttpContext.Current.ApplicationInstance.CompleteRequest();

这应该可以防止你看到的两次火灾。

vptzau2j

vptzau2j6#

一种可能性是你可能没有考虑到其他正在进行的请求。例如,假设你的ASPX页面引用了一些图像或CSS文件。如果这些请求通过ASP.NET管道,那么你的模块将被调用,它们将被注册为命中。
另外,当你说IHttpModule.BeginRequest时,你的意思是在IHttpModule.Init()中你连接了HttpApplication.BeginRequest吗?如果是这样,那么我上面提到的原因可能仍然适用。

8oomwypt

8oomwypt7#

在Visual Studio 2013及更高版本中禁用Browser Link,这会导致第二个请求。

从Visual Studio运行应用程序时会发生这种情况。

相关问题