IHttpModule.BeginRequest firing 2X, Application_BeginRequest firing 1X

不问归期 提交于 2019-12-12 10:43:51

问题


I'm running VS 2008 and .NET 3.5 SP1.

I want to implement hit tracking in an HttpModule in my ASP.NET app. Pretty simple, I thought. However, the BeginRequest event of my HttpModule is firing twice for each page hit. The site is very simple right now...no security, just a bit of database work. Should log one row per page hit. Why is this event firing twice?

Moreover, IHttpModule.BeginRequest actually fires a different number of times for the first page hit when running for the first time (from a closed web browser)...3 times when I'm hitting the DB to provide dynamic data for the page, and only 1 time for pages where the DB isn't hit. It fires 2 times for every page hit after the first one, regardless of whether or not I'm touching the DB.

It's interesting to note that Application_BeginRequest (in Global.asax) is always firing only once.

Here's the code:

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 "";
        }
    }
}

回答1:


This might be too late for the answer but can be useful for someone else. I faced with the same problem. BeginRequest event triggered for twice for each request. I debugged the code and realized that the first trigger for actual resource request but the second is result of "favicon.ico" request. At the beginning of BeginRequest event, a simple check for favicon.ico request eliminates second execution of the method.

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

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



回答2:


This is interesting. I removed the reference to the CSS file from the master page and I'm getting fewer repeat hits in the HttpModule for certain browsers (as was suggested), but I'm still getting repeats. I've got 6 browsers installed and I'm getting some variation between them.

For reference, this is the URL I'm plugging in to my browsers for this test:

http://localhost/BluHeron

default.aspx is set as the start page and is, in fact, getting returned for the aforementioned URL. I'm using HttpRequest.RawUrl for reporting which page the user hit. Specifically, I'm splitting the RawUrl string and just reporting the last item in the array of strings (see code).

  • Every single browser is reporting hitting default.aspx, as expected (RawUrl = /BluHeron/default.aspx).
  • 4 of the 6 browsers are also reporting BluHeron (RawUrl = /BluHeron).
  • 3 of the 6 browsers are also recording a blank in the database (RawUrl = /BluHeron/).

There are a couple ways I can get accurate reporting of how many people are hitting which pages.

  1. select from the database only rows that actually list one of my pages (ignore /BluHeron and blanks)
  2. Just use Application_BeginRequest in the global.asax file (that seems to consistently get called only once per page hit)
  3. Get this figured out

So, I've got options for getting good reports even with crappy data in the database. I would, however, prefer not to have junk in the database, and to understand what's going on here.

Thanks for looking, everyone!




回答3:


quite late on this, but ran into the same issue. In our case it was due to the anonymous request first that returns the 401 per the RFC. The second request authenticates.




回答4:


The "Default Document" part of IIS seems to fire a second BeginRequest event. If you have determined that the Request.Path is the same for the HttpApplication in both event handlers and your url ends with a slash, try adding a URL Rewrite rule to shortcut the "Default Document" processing.




回答5:


One possibility is that there are other requests going on that you might not be considering. For example, let's say your ASPX page references some images or CSS files. If those requests go through the ASP.NET pipeline then your module will be called and they'll register as hits.

Also, when you say IHttpModule.BeginRequest do you mean that in IHttpModule.Init() you are hooking up HttpApplication.BeginRequest? If so then the reason I mention above might still apply.




回答6:


We solved this by using

HttpContext.Current.ApplicationInstance.CompleteRequest();

This should prevent the the twice fire you are seeing.




回答7:


Disable Browser Link in Visual Studio 2013 and up, which causes the second request.

This occurs when an Application is run from Visual Studio.



来源:https://stackoverflow.com/questions/2181648/ihttpmodule-beginrequest-firing-2x-application-beginrequest-firing-1x

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!