我需要使用HttpModule编写一个自定义的"UrlRewriter“,在”重写“的那一刻,我需要访问会话,并且遵循了另一个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; }
}
}
}
}发布于 2009-02-12 08:40:03
我想我知道是什么了。您的模块将在所有请求上执行,并分配一个处理程序,该处理程序将抛出错误,除非存在有效的活动代码(其中发生了重写/重定向)。
但是因为这不仅仅是为了你的“处理程序活动代码”url,它会导致抛出一个错误,这会导致你被重定向到你的错误页面,这个页面被分配给处理程序的模块捕获,这个处理程序抛出一个错误,这是重定向的……我想你已经明白我要说的了;)
否则,我会尝试以下几种方法:
发布于 2009-02-12 08:28:14
我写了一个简单的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页未找到错误。
最后一种方法运行良好,但与Response.Redirect方法一样,用户将在其浏览器中看到新的url。使用Context.RewritePath允许您提供与请求的页面不同的页面。
发布于 2009-02-05 20:06:16
您的URL重写器是否正在处理不是针对实际页面的请求?如果它们是,那么我不认为你可以访问会话...我写的上一个URL重写器是用来处理404错误的,我记得我深入研究发现(在某个地方,我记不住在哪里了),如果会话请求不是针对一个实际的.aspx页面,您就无法访问该会话。
https://stackoverflow.com/questions/506431
复制相似问题