每次请求都不会调用HttpModule

时间:2012-08-01 09:08:16

标签: c# asp.net .net httpmodule

我有一个安装在我们服务器上的HTTP模块。奇怪的是它有效,但每隔一段时间它就没有被执行。我有日志记录,并且在它不起作用的时候它没有到达记录的代码。我在IIS日志或事件查看器中看不到任何内容。

    namespace RedirectModule
    {
        public class RedirectModule : System.Web.IHttpModule
        {
            private const string MobileUserAgent = "MobileUserAgentCacheKey";

            private const string 

STRING_TO_FIND = "info/lps";
        private const string STRING_TO_ADD = "/mobile";


        public void Dispose()
        {
            //clean-up code here.
        }

        public void Init(HttpApplication context)
        {          
            context.BeginRequest += context_BeginRequest;
        }
        private static object sync = new object();
        private void context_BeginRequest(object sender, EventArgs e)
        {

            try
            {


                HttpContext context = HttpContext.Current;


                string url = context.Request.Url.ToString().ToLower();

                if (!url.Contains(STRING_TO_FIND) || url.Contains(STRING_TO_FIND + STRING_TO_ADD))
                    return;
                Logger.Current.Log("Starting Redirect Phase");

                if (XmlToValues.IsMobile(context.Request.ServerVariables["HTTP_USER_AGENT"],
                                       GetCachedFile(context, "Settings.xml")))
                {
                    var mobileRedirect = GetRedirectUrl(url, STRING_TO_FIND, STRING_TO_ADD);
                    if (mobileRedirect != null)
                    {
                        Logger.Current.Log("Redirect to Mobile page");
                        context.Response.Redirect(mobileRedirect);

                    }
                }
                Logger.Current.Log("Web Page");
                Logger.Current.Log("End Begin Request");
            }
            catch (Exception ex)
            {
                if (ex is ThreadAbortException)
                    return;

                Logger.Current.LogError(ex);

            }
        }


        public static string GetRedirectUrl(string url, string strToFind, string strToAdd)
        {
            try
            {
                Logger.Current.Log("Get Redirect Url ");
                int idx = url.IndexOf(strToFind) + strToFind.Length;
                return url.Substring(0, idx) + strToAdd + url.Substring(idx);
            }
            catch (Exception ex)
            {

                Logger.Current.LogError(ex);


                return null;
            }
        }



        private XmlNodeList GetCachedFile(HttpContext context, string filePath)
        {
            try
            {
                Logger.Current.Log("GetCachedFile START");
                if (context.Cache[MobileUserAgent] == null)
                {
                    context.Cache[MobileUserAgent] = XmlToValues.GetMobileUserAgents(filePath);
                    Logger.Current.Log("Add Mobile File to Cache");
                }
                return (XmlNodeList)context.Cache[MobileUserAgent];
            }
            catch (Exception ex)
            {
                Logger.Current.LogError(ex);

                return null;
            }
        }

    }
}

和我的Web.Config:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>


  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <remove name="RedirectModule" />
      <add name="RedirectModule" type="RedirectModule.RedirectModule, RedirectModule" />


    </modules>
    <handlers>
      <remove name="Redirect" />
    </handlers>
    <validation validateIntegratedModeConfiguration="false"/>
  </system.webServer>
  <system.web>
    <httpModules>
      <add name="RedirectModule" type="RedirectModule.RedirectModule, RedirectModule" />
    </httpModules>
    <compilation debug="true">    
    </compilation>
  </system.web>
</configuration>

P.S。我在web.config中取出了log4net,因为它很麻烦。

以下是该项目的链接:http://www.sendspace.com/file/w42me5

这是被请求页面的标记,它位于一个名为index.htmnl的文件中:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<!-- no cache headers -->
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="no-cache">
<meta http-equiv="Expires" content="-1">
<meta http-equiv="Cache-Control" content="no-cache">
<!-- end no cache headers -->
</head>
<body>
MOBILE
</body>
</html>

2 个答案:

答案 0 :(得分:0)

我有一个类似的问题...尝试在你的webbrowser中转换缓存并再试一次。要关闭此请求的缓存,您需要修改响应头。 Example on modifying caching option

答案 1 :(得分:0)

听起来你可能正在浏览器和服务器之间的某个地方点击缓存。缓存有很多潜在的地方,这里有一些尝试找到它的一般步骤:

  • 浏览器 - 浏览器不必请求缓存的内容。 This question列出了不同浏览器的工具,以确认发送的请求。
  • 客户端计算机 - 如果从浏览器发送请求,您可能会有一个代理(如Squid)返回缓存数据。您可以使用Fiddler检查HTTP请求是否已离开客户端计算机。
  • 网络代理 - 与客户端计算机相同,只是代理位于网络上的某个服务器上。您必须在代理服务器上分析传出的HTTP流量,以确定是否正在发送请求。
  • Web服务器 - 您的重定向模块可以提供缓存内容,而不是将其呈现为新内容。在这种情况下,它应该显示在您的日志中。将日志调用添加到BeginRequest处理程序的最开头,以确认请求是否实际上是否已发送到您的服务器。

要防止缓存,您可以向请求添加无缓存标头(文章here):

        private void Application_EndRequest(Object source, EventArgs e) 
        {
            HttpApplication application = (HttpApplication)source;
            HttpContext context = application.Context;
            context.Response.ExpiresAbsolute = DateTime.Now.AddDays( -100 );
            context.Response.AddHeader( “pragma”, “no-cache” );
            context.Response.AddHeader( “cache-control”, “private” );
            context.Response.CacheControl = “no-cache”;
        }

修改

调试到服务器的请求

响应中的HTTP 200表明您很可能没有缓存问题。要确认每个请求实际上得到到服务器,尝试添加日志到您的Application_BeginRequest处理程序(在Global.asax中)来记录每一个请求,并把它比作在你context_BeginRequest生成的日志你的HTTP模块。

//In Global.asax
private void Application_BeginRequest(Object source, EventArgs e) {
    Logger.Current.Log("Request made to Application_BeginRequest")
}

//In your HttpModule
    private void context_BeginRequest(object sender, EventArgs e)
    {
        //Log before any of your other code
        Logger.Current.Log("Request made to context_BeginRequest")

        try
        {
              // your code
        }
        catch (Exception ex)
        {
            // log the exception first in case this is the problem
            Logger.Current.LogError(ex);

            if (ex is ThreadAbortException)
                return;

        }
    }

解释结果

在没有到达您的模块的请求后检查您的日志。

  • 如果没有显示任何内容,请求永远不会进入您的服务器。见上文关于缓存
  • 如果您的日志以请求发送到Application_BeginRequest 结束,则表示您的模块未被调用。
  • 如果它以请求发送到context_BeginRequest 结束,则在您的记录器之前模块代码中出现错误,导致某些请求崩溃。这可能是空引用HttpContext.Current,或者,或溢出问题,或任何其他数量的问题。这应该由你的finally语句记录。