IIS7 の 404 + HttpHandler にフォームを投稿します。POST データがすべて失われているのはなぜですか?

StackOverflow https://stackoverflow.com/questions/102846

  •  01-07-2019
  •  | 
  •  

質問

OK、これは少し混乱して複雑に聞こえるかもしれませんが、ご了承ください。

フレンドリーな URL を定義できるフレームワークを作成しました。任意の URL にアクセスすると、IIS は 404 エラー (場合によっては 403;14 または 405) を表示しようとします。ただし、IIS は、これらの特定のエラーに関連するものはすべて .aspx ファイルに送信されるように設定されています。これにより、HttpHandler を実装してリクエストを処理したり、関連するテンプレートを見つけて、それに関連付けられたものを実行したりすることができます。

さて、これはすべて IIS 5 と 6、そしてある程度は IIS7 でも機能しますが、フォームを投稿するときに発生する 1 つの問題点があります。

存在しない URL にフォームを投稿すると、IIS は「ああ、でもその URL は存在しません」と言って、405「メソッドが許可されていません」エラーをスローします。これらのエラーを .aspx ページにリダイレクトし、HttpHandler で処理するように IIS に指示しているため、通常、これは問題になりません。しかし、IIS7 では、すべての POST 情報が 405 にリダイレクトされた後に失われています。そのため、フォームに関係する最も些細な作業はできなくなります。

これを解決するために、HttpModule を使用してみました。これは POST データを保存しますが、適切なタイミング (必要なとき) にセッションが初期化されていないように見えます。また、404/403;14/405 にヒットした欠落リクエストだけでなく、すべてのリクエストに対して HttpModule を使用することも試みましたが、これは画像、CSS、JS などのものが .NET コードによって処理されることを意味し、非常に非効率的です。

ここで実際の質問に移ります。誰かがこれに遭遇したことがありますか、誰かが何かアドバイスを持っているか、物事を再び動作させるために何をすべきか知っていますか?これまでのところ、誰かがMicrosoft独自のものを使用することを提案しています URL書き換えモジュール. 。これは問題の解決に役立つでしょうか?

ありがとう。

役に立ちましたか?

解決

Microsoft はこれに対するホットフィックスをリリースしました。

http://support.microsoft.com/default.aspx/kb/956578

他のヒント

IIS7 はトップダウンで .net を使用するため、HttpModule の使用によるパフォーマンスのオーバーヘッドはありません。実際、すべての要求で常に使用される管理対象 HttpModule がいくつかあります。BeginRequest イベントが発生したときに、SessionStateModule が Modules コレクションに追加されていない可能性があるため、このイベント中にリクエストを処理しようとしても、セッション状態情報は利用できません。HttpContext.Handler プロパティを設定すると、要求されたハンドラーが必要とする場合にセッション状態が初期化されるため、ハンドラーを IRequiresSessionState を実装する派手な 404 ページに設定するだけで済みます。以下のコードでうまくいきますが、IsMissing() メソッドの別の実装を記述する必要がある場合があります。

using System.Web;
using System.Web.UI;

class Smart404Module : IHttpModule
{
    public void Dispose() {}

    public void Init(HttpApplication context)
    {
        context.BeginRequest += new System.EventHandler(DoMapping);
    }

    void DoMapping(object sender, System.EventArgs e)
    {
        HttpApplication app = (HttpApplication)sender;

        if (IsMissing(app.Context))
            app.Context.Handler = PageParser.GetCompiledPageInstance(
                "~/404.aspx", app.Request.MapPath("~/404.aspx"), app.Context);
    }

    bool IsMissing(HttpContext context)
    {
        string path = context.Request.MapPath(context.Request.Url.AbsolutePath);

        if (System.IO.File.Exists(path) || (System.IO.Directory.Exists(path)
            && System.IO.File.Exists(System.IO.Path.Combine(path, "default.aspx"))))
            return true;
        return false;
    }
}

編集:IsMissing() の実装を追加しました

注記:IIS7 では、セッション状態モジュールはデフォルトではグローバルに実行されません。次の 2 つのオプションがあります。すべてのリクエストに対してセッション状態モジュールを有効にするか (すべてのリクエスト タイプに対するマネージド モジュールの実行に関する上記のコメントを参照)、リフレクションを使用して System.Web.dll 内の内部メンバーにアクセスすることもできます。

IIS 7 でポスト変数がカスタム エラー ハンドラーに渡されないという問題は、Vista の Service Pack 2 で修正されています。Windows Server では試していませんが、Windows Server でも修正されると思います。

単なる推測です:リクエストを処理する IIS7 の %windir%\system32\inetsrv\config\applicationhost.config で指定されたハンドラーは、POST 動詞の通過をまったく許可しておらず、URL が存在するかどうかを判断する前にそのルールを評価しています。 。

はい、URL の書き換え (Microsoft の IIS7 の 1 つまたは多くの代替手段の 1 つを使用) を間違いなくお勧めします。これはわかりやすい URL を提供するために特別に設計されていますが、エラー ドキュメントは障害に対する最後の手段であり、受信データが変更される傾向があるため、期待どおりにならない可能性があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top