我在IIS7上运行的ASP.NET 3.5应用程序中使用Context.RewritePath()。
我在应用程序BeginRequest事件中执行此操作,一切正常。
/ sports的请求被正确地重写为default.aspx?id = 1,依此类推。
问题是,在我的IIS日志中,我看到了对/Default.aspx?id=1的GET请求,而不是/ sports。
这种代码在IIS6下完美运行。
由于必须实施某些业务逻辑,因此不能使用Microsoft Rewrite模块。
感谢。
编辑:
似乎我的处理程序在管道中太早了,但是如果我将逻辑移动到后来的事件,那么整个重写的东西都不起作用(为时已晚,StaticFileHandler接收我的请求)。
我用谷歌搜索并用谷歌搜索,不敢相信没有人有这个问题?编辑:
糟糕!这是我在IIS论坛上发现的:
“这是因为在集成模式下,IIS和asp.net共享一个公共管道,现在IIS可以看到RewritePath,而在IIS6中,它甚至没有被IIS看到 - 你可以通过使用经典模式来解决这个问题。会表现得像IIS6。“
最终更新:请查看my answer below,我在生产环境中使用了一年多的时间后对结果进行了更新。
答案 0 :(得分:6)
经过一番研究,我终于找到了解决问题的方法。
我已使用new(在ASP.NET 3.5中引入) Context.Server.TransferRequest()方法替换了对Context.RewritePath()方法的调用。
现在看来很明显,但IIS核心团队的高级开发工程师事件并没有想到这一点。
我已经测试了会话,身份验证,回发,查询字符串......问题,但没有找到。
Tommorow我会将更改部署到一个非常高的交通网站,我们很快就会知道它是如何运作的。 :)
我会回来更新。
更新:解决方案仍然不完全在我的生产服务器上,但它已经过测试,它确实有效,据我所知,到目前为止,这是我的问题的解决方案。如果我在生产中发现任何其他内容,我会发布更新。
最终更新:我已经将这个解决方案投入生产一年多了,它已被证明是一个不错的稳定解决方案。
答案 1 :(得分:4)
您可以在处理请求之后但在IIS日志记录模块写入日志条目之前将路径设置回原始值。
例如,此模块会重写BeginRequest
上的路径,然后将其设置回EndRequest
上的原始值。使用此模块时,原始路径将显示在IIS日志文件中:
public class RewriteModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.BeginRequest += OnBeginRequest;
context.EndRequest += OnEndRequest;
}
static void OnBeginRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
app.Context.Items["OriginalPath"] = app.Context.Request.Path;
app.Context.RewritePath("Default.aspx?id=1");
}
static void OnEndRequest(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var originalPath = app.Context.Items["OriginalPath"] as string;
if (originalPath != null)
{
app.Context.RewritePath(originalPath);
}
}
public void Dispose()
{
}
}
答案 2 :(得分:2)
我遇到了完全相同的问题。解决此问题的一种方法是使用Server.Transfer而不是Context.RewritePath。 Server.Transfer不会重新启动整个页面生命周期,因此仍会记录原始URL。请确保为“preserveForm”参数传递“true”,以便QueryString和Form集合可用于第2页。
答案 3 :(得分:0)
老问题,但我发现在执行以下操作时我没有遇到您的问题:
a)web.config中的重写规则,用于将所有请求定向到/default.aspx,例如:
<rule name="all" patternSyntax="Wildcard" stopProcessing="true">
<match url="*"/>
<action type="Rewrite" url="/default.aspx"/>
</rule>
b)在default.aspx的Page_PreInit
事件中调用RewritePath,将URL和查询字符串重写为请求中传递的内容(即不存在的位置)。
例如,我请求“/ somepage /?x = y”(不存在)。
a)Web.config规则将其映射到/default.aspx
b)Page_PreInit将其重写为“/ somepage /?x = y”。
在IIS 7(Express和生产)中,结果是服务器日志反映了存根的“/ somepage”和查询的“x = y”,并且所有Request对象属性都反映了所请求的(不存在) )URL(这是我想要的)。
唯一奇怪的效果是,在IIS Express中,日志项被写入两次。但是,这在生产中不会发生(Windows Server 2008 R2)。