IIS7,RewritePath和IIS日志文件

时间:2008-12-09 17:15:27

标签: c# asp.net iis-7 url-rewriting logging

我在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,我在生产环境中使用了一年多的时间后对结果进行了更新。

4 个答案:

答案 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)。