asp.net - IHttpModule.BeginRequest 触发 2X,Application_BeginRequest 触发 1X

标签 asp.net httpmodule

我正在运行 VS 2008 和 .NET 3.5 SP1。

我想在 HttpModule 中实现命中跟踪在我的 ASP.NET 应用程序中。很简单,我想。然而,BeginRequest我的事件 HttpModule每次点击页面都会触发两次。该站点现在非常简单......没有安全性,只是一些数据库工作。每页命中应记录一行。为什么这个事件会触发两次?

此外,IHttpModule.BeginRequest第一次运行时(从关闭的 Web 浏览器),实际上为第一页命中触发了不同的次数......当我点击 DB 为页面提供动态数据时,只有 1 次为未命中数据库的页面。无论我是否在接触数据库,它都会在第一个页面点击后触发 2 次。

有趣的是,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 "";
        }
    }
}

最佳答案

这对于答案可能为时已晚,但对其他人可能有用。我遇到了同样的问题。每个请求触发两次 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; }

关于asp.net - IHttpModule.BeginRequest 触发 2X,Application_BeginRequest 触发 1X,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2181648/

相关文章:

c# - 如何在 asp :checkboxlist 中获取所选项目的计数

c# - IIS 在第一个请求和后续请求中以不同方式处理 URL 中的双编码正斜杠

asp.net - 无法访问 Httpmodule 中的静态资源(例如 css/js/image 文件)的 session

c# - 重置密码电子邮件...最近的电子邮件应该有效,而不是以前的电子邮件

asp.net - 如何为Asp.Net中的所有子文件夹注册HttpHandler?

asp.net-mvc - 创建 Asp.net MVC 3 应用程序时找不到关于 UrlRoutingModule 的 <modules>

c# - HttpModule 和静态类,多个请求共享同一个静态数据吗?

asp.net - 如何从头开始为 Asp.Net 应用程序设置远程调试

asp.net - Cookie文件的最大大小是多少?

c# - Linq 返回没有跟进记录的记录