10

IIS7 で実行されている ASP.NET 3.5 アプリケーションで Context.RewritePath() を使用しています。

私はアプリケーションの BeginRequest イベントでそれを行っており、すべてがファイルで動作します。

/sports の要求は、default.aspx?id=1 などに正しく書き換えられます。

問題は、私の IIS ログに、/sports ではなく、/Default.aspx?id=1 に対する GET 要求が表示されることです。

この種のコードは、IIS6 で完全に機能しました。

ビジネス ロジックを実装する必要があるため、Microsoft Rewrite モジュールを使用することはできません。

ありがとう。

編集:

ハンドラーがパイプラインで早すぎるようですが、ロジックを後のイベントに移動すると、書き換え全体が機能しません (遅すぎて、StaticFileHandler が要求を受け取ります)。

私はググってググって、周りに尋ねましたが、誰もこの問題を抱えていないとは信じられませんか?

編集:

うわぁ!IISフォーラムで見つけたものは次のとおりです。

「これは、統合モードでは IIS と asp.net が共通のパイプラインを共有し、RewritePath が IIS によって認識されるようになったためです。一方、IIS6 では、IIS によってさえ認識されませんでした。次のように動作するクラシック モードを使用することで、これを回避できます。 IIS6.」

最終更新:以下の私の回答をご覧ください。実稼働環境で 1 年以上経過した結果を更新しました。

4

4 に答える 4

6

いくつかの調査の後、私は最終的に問題の解決策を見つけました。

Context.RewritePath() メソッドの呼び出しを新しい (ASP.NET 3.5 で導入された) Context.Server.TransferRequest () メソッドに置き換えました。

今では当たり前のように思えますが、IIS コア チームのシニア開発エンジニアがそのことを考えたことはありませんでした。

セッション、認証、ポストバック、クエリ文字列などの問題についてテストしましたが、何も見つかりませんでした。

明日、この変更を非常にトラフィックの多いサイトに展開します。実際にどのように機能するかはすぐにわかります。:)

アップデートで戻ってきます。

更新:ソリューションはまだ完全に実稼働サーバー上にあるわけではありませんが、テスト済みで動作します。これまでのところ、これは私の問題の解決策です。本番環境で何か他のことを発見した場合は、更新を投稿します。

最終更新:私はこのソリューションを 1 年以上実稼働しており、問題なく優れた安定したソリューションであることが証明されています。

于 2009-02-23T20:15:10.610 に答える
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()
    {

    }
}
于 2009-02-17T18:14:37.280 に答える
2

私はまったく同じ問題を抱えていました。これを回避する 1 つの方法は、Context.RewritePath の代わりに Server.Transfer を使用することです。Server.Transfer はページのライフサイクル全体を再開しないため、元の URL は引き続きログに記録されます。2 ページ目で QueryString コレクションと Form コレクションを使用できるように、必ず「preserveForm」パラメーターに「true」を渡してください。

于 2009-02-17T18:34:12.693 に答える
0

古い質問ですが、次のことを行ったときに問題が発生しなかったことがわかりました。

a) すべてのリクエストを /default.aspx に送信するための web.config の書き換えルール。

    <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 (高速および運用) では、サーバー ログはスタブの "/somepage" とクエリの "x=y" を反映し、すべての Request オブジェクト プロパティは要求された (存在しない) URL を反映します (これは私が欲しかったものです)。

唯一の奇妙な影響は、IIS Express でログ項目が 2 回書き込まれることです。ただし、これは運用環境 (Windows Server 2008 R2) では発生しません。

于 2013-01-06T09:54:09.787 に答える