【问题标题】:UrlRewriter+HttpModule+Session problemUrlRewriter+HttpModule+Session问题
【发布时间】:2009-02-03 09:04:23
【问题描述】:

我需要使用 HttpModule 编写自定义“UrlRewriter”,在“重写”的那一刻,我需要访问 Session 并遵循另一个 SO 线程的建议:

Can I access session state from an HTTPModule?

一切正常,除了 RewritePath/Redirect 部分。我没有任何异常,但浏览器需要永远加载。这真的是构建这样一个 urlrewriter 的最佳方式吗?

using System;
using System.Web;
using System.Web.SessionState;
using System.Diagnostics;

namespace MyCompany.Campaigns
{

    public class CampaignRewriteModule : IHttpModule
    {
        public void Init(HttpApplication application)
        {
            application.PostAcquireRequestState += new EventHandler(Application_PostAcquireRequestState);
            application.PostMapRequestHandler += new EventHandler(Application_PostMapRequestHandler);
        }

        void Application_PostMapRequestHandler(object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication)source;

            if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState)
            {
                return;
            }

            app.Context.Handler = new MyHttpHandler(app.Context.Handler);
        }

        void Application_PostAcquireRequestState(object source, EventArgs e)
        {
            HttpApplication app = (HttpApplication)source;

            MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;

            if (resourceHttpHandler != null)
            {
                HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
            }

            Debug.Assert(app.Session != null);


            string path = HttpUtils.Path();

            if (!CampaignCodeMethods.IsValidCampaignCode(path)) return;

            string domain = HttpUtils.Domain();

            CampaignCode code = CampaignManager.RegisterCode(path, domain.Equals(Config.Instance.Domain.ToLower()) ? null : domain);

            if (code != null)
            {
               //app.Context.RewritePath(code.CampaignCodePath.Path, false);
               app.Context.Response.Redirect(code.CampaignCodePath.Path, true);
            }


        }

        public void Dispose() { }

        public class MyHttpHandler : IHttpHandler, IRequiresSessionState
        {
            internal readonly IHttpHandler OriginalHandler;

            public MyHttpHandler(IHttpHandler originalHandler)
            {
                OriginalHandler = originalHandler;
            }

            public void ProcessRequest(HttpContext context)
            {
                throw new InvalidOperationException("MyHttpHandler cannot process requests.");
            }

            public bool IsReusable
            {
                get { return false; }
            }
        }

    }

}

【问题讨论】:

  • 这和浏览器有什么关系?如果是这样,您使用的是什么浏览器?

标签: c# asp.net


【解决方案1】:

我想我知道它是什么。您的模块在所有请求上执行,并分配一个引发错误的处理程序,除非存在有效的活动代码(发生重写/重定向)。

但是因为这不仅适用于您的“处理程序广告系列代码”网址,它会导致引发错误,从而导致您被重定向到错误页面,该页面正在被分配处理程序,它抛出一个错误,它正在重定向......我想你得到了我要去的地方;)

否则我会尝试一些事情:

  • 设置 Fiddler 并检查无限重定向循环
  • 在 app.Context.Response.Redirect 上设置断点 - 确保您没有处于无限循环中
  • 在 MyHttpHandler.ProcessRequest 上放置一个断点 - 确保它没有被调用并且异常被吞没

【讨论】:

    【解决方案2】:

    我编写了一个简单的 URL 重写器模块,它做了类似的事情。通过将请求的 url 与已知 url 列表进行比较,在 BeginRequest 中完成 url 重写。如果我们找到一个 mach,我们使用 HttpContext.RewritePath 来更改请求的 url。

    这似乎运作良好,没有严重的副作用。

    我注意到您使用 Response.Redirect 而不是 Context.RewritePath。使用重定向将导致用户浏览器请求具有新 url 的新页面。这真的是你想要的吗?然后,用户将在他的浏览器中看到新的 url。如果这确实是您想要的,您可以使用另一种方法,使用自定义 404 页面未找到错误处理程序将用户重定向到适当的页面。

    如果您将 IIS 设置为将所有 404 错误重定向到您已设置的新页面,例如 Custom404.aspx。在此页面中,您可以检查请求的 url 以查看是否应重写 url。如果需要,您可以简单地将 Response.Status 设置为“301 Moved Permanently”,并编写一个名为“Location”的标题,并将新的 url 作为值。如果 url 不应该被重写,你可以输出标准的 404 page not found 错误。

    最后一种方法效果很好,但与您的 Response.Redirect 方法一样,用户将在其浏览器中看到新的 url。使用 Context.RewritePath 可以让您提供与请求的页面不同的页面。

    【讨论】:

      【解决方案3】:

      您的 URL 重写器是否在处理并非针对实际页面的请求?如果是,那么我认为您无法访问 Session... 我写的最后一个 URL 重写器是用来处理 404 错误的,我记得四处挖掘并发现(某个地方,不记得在哪里)你如果该请求不是针对实际的 .aspx 页面,则无法访问 Session。

      【讨论】:

        【解决方案4】:

        我认为问题可能出在这个块内:

        if (code != null)
        {
            //app.Context.RewritePath(code.CampaignCodePath.Path, false);
            app.Context.Response.Redirect(code.CampaignCodePath.Path, true);
        }
        

        尝试在if 语句中放置一个断点,看看是否不断被命中。

        【讨论】:

          【解决方案5】:

          我认为在将其重置为原始处理程序后应该调用“return”,否则您将不断重写路径。

          仔细想想,这可能就是页面永远加载的原因! :)

          【讨论】:

            猜你喜欢
            • 2011-08-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-03
            • 1970-01-01
            • 2011-12-19
            • 2018-03-22
            相关资源
            最近更新 更多