10

我在 IIS7 上运行的 ASP.NET 3.5 应用程序中使用 Context.RewritePath()。

我在应用程序 BeginRequest 事件中执行此操作,并且一切正常文件。

/sports 的请求被正确地重写为 default.aspx?id=1,依此类推。

问题是在我的 IIS 日志中,我看到 /Default.aspx?id=1 的 GET 请求,而不是 /sports 的 GET 请求。

这种代码在 IIS6 下完美运行。

由于必须实现一些业务逻辑,因此不能选择使用 Microsoft Rewrite 模块。

谢谢。

编辑:

似乎我的处理程序在管道中为时过早,但是如果我将逻辑移到以后的事件中,那么整个重写的事情就不起作用了(为时已晚,StaticFileHandler 接受了我的请求)。

我用谷歌搜索和谷歌搜索,四处询问,不敢相信没有人有这个问题?

编辑:

哎呀!这是我在 IIS 论坛上找到的内容:

“这是因为在集成模式下,IIS 和 asp.net 共享一个公共管道,并且现在 IIS 可以看到 RewritePath,而在 IIS6 中,IIS 甚至都看不到它 - 您可以使用经典模式来解决这个问题,其行为类似于IIS6。”

最终更新:请看下面我的回答,我在生产环境中使用了一年多后更新了结果。

4

4 回答 4

6

经过一番研究,我终于找到了解决问题的方法。

我已经用新的(在 ASP.NET 3.5 中引入) Context.Server.TransferRequest()方法替换了对 Context.RewritePath() 方法的调用。

现在看起来很明显,但 IIS 核心团队的高级开发工程师没有想到这一点。

我已经针对会话、身份验证、回发、查询字符串等问题对其进行了测试,但没有发现任何问题。

明天我会将更改部署到一个流量非常大的站点,我们很快就会知道它是如何工作的。:)

我会回来更新的。

更新:该解决方案仍然不完全在我的生产服务器上,但它已经过测试并且确实有效,据我所知,它是我的问题的解决方案。如果我在生产中发现任何其他内容,我将发布更新。

最后更新:我在生产中使用了这个解决方案一年多了,它已被证明是一个良好且稳定的解决方案,没有任何问题。

于 2009-02-23T20:15:10.610 回答
4

您可以在处理请求之后但在 IIS 日志记录模块写入日志条目之前将路径设置回原始值。

例如,此模块重写路径 onBeginRequest然后将其设置回原始值 on 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()
    {

    }
}
于 2009-02-17T18:14:37.280 回答
2

我遇到了完全相同的问题。解决此问题的一种方法是使用 Server.Transfer 而不是 Context.RewritePath。Server.Transfer 不会重新启动整个页面生命周期,因此仍会记录原始 URL。确保为“preserveForm”参数传递“true”,以便 QueryString 和 Form 集合可用于第二页。

于 2009-02-17T18:34:12.693 回答
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 事件中调用 RewritePath,Page_PreInit将 URL 和查询字符串重写为请求中传递的内容(即不存在的位置)。

例如,我请求“/somepage/?x=y”(不存在)。

a) Web.config 规则将其映射到 /default.aspx

b) Page_PreInit 将其重写回“/somepage/?x=y”。

结果,在 IIS 7(Express 和生产)中,服务器日志反映了存根的“/somepage”和查询的“x=y”,并且所有请求对象属性都反映了请求的(不存在的)URL(这就是我想要的)。

唯一奇怪的效果是,在 IIS Express 中,日志项被写入了两次。但是,这不会在生产中发生(Windows Server 2008 R2)。

于 2013-01-06T09:54:09.787 回答