3

我在我们的服务器上安装了一个 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>

ps 我在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>
4

2 回答 2

0

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

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

为了防止缓存,您可以在请求中添加无缓存标头(此处的文章):

        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 中)以记录每个请求并将其与 HttpModule 中的 context_BeginRequest 生成的日志进行比较。

//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;

        }
    }

解释结果

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

  • 如果它什么也没显示,则该请求永远不会到达您的服务器。见上文关于缓存
  • 如果您的日志以Request made to Application_BeginRequest结束,则您的模块没有被调用。
  • 如果它以Request made to context_BeginRequest结束,那么在您的记录器之前的模块代码中存在错误,这会导致某些请求崩溃。这可能是一个空引用 HttpContext.Current,或 Request,或溢出问题,或任何其他事情。这应该由您的 finally 语句记录。
于 2012-08-05T07:22:40.453 回答
0

我有一个类似的问题...尝试在您的网络浏览器中关闭缓存,然后重试。为了关闭此请求的缓存,您需要修改响应标头。修改缓存选项的示例

于 2012-08-01T12:45:17.530 回答