none
*.aspxで指定したレスポンスを無効にしたい RRS feed

  • 質問

  • 最近ASP.NETを始めましたので、トンチンカンな事を言っているかもしれませんがご容赦ください。

    例えば、Default.aspx、Dafault.aspx.csという二つのファイルで構成しているページで、Default.aspx.cs内で

    Response.Write("<html>・・・</html>");

    のようにレスポンスを定義し、Default.aspxで定義している内容を無効にして(Default.aspxに書かれている内容を無視して)、上記処理の内容だけのレスポンスとしたいのですが、どのようにしたら良いでしょうか?

    現在、ブラウザで確認すると、上記処理で出力した内容の後に、Default.aspxで定義している内容が出力されています。

    なお、ちょっと理由があって、上記処理はPage_PreRenderメソッド内に実装しています。

    また、Response.Clear や Response.ClearContent を試して見ましたが無効にはなりませんでした。

    よろしくお願いします。

    2014年6月19日 1:39

回答

  • Hoshinaです
    こんにちは

    やりたい事がよく分かっていない可能性がありますが,aspxではなくashxを使用することで解決しませんか?

    新しい項目の追加で選択できるものを順に確認して,拡張子が「ashx」のものを選択してみてください。

    それでは

    • 回答としてマーク yana_tak 2014年6月19日 2:47
    2014年6月19日 1:55
  • このケースに適合するかわかりませんが、Response.End()はダメでしょうか? ただし、このメソッドは例外を発生させますので、以下のように握りつぶさないとダメなような気がしますが・・・

    try
    {
        Response.End();
    }
    catch
    {
    }


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク yana_tak 2014年6月19日 2:47
    2014年6月19日 2:05
    モデレータ
  • 何故そのようなことをする必要があるのかの議論はちょっと置いといて・・・(他にやり方があると思われ)

    > 現在、ブラウザで確認すると、上記処理で出力した内容の後に、Default.aspxで定義
    > している内容が出力されています。

    デフォルトで作ると Default.aspx には <!DOCTYPE ... で始まる html コードが含まれるはずですが、サーバーはそれもクライアントに送信してから終了します。

    Response.Write("<html>・・・</html>"); のあと <!DOCTYPE ... で始まる html コードが送信されないようにするには、他の回答者の方の回答とダブりますが、以下の方法があります。

    (1) Response.Write("<html>・・・</html>"); の直後に Response.End(); として強制終了する。

    (2) <!DOCTYPE ... で始まる html コードを全て削除する。

    (3) .aspx ページを使うのは止めてジェネリック HTTP ハンドラ (.ashx) を使う。

    お勧めは (3) です。

    局所的な部分の質問だけでなく、何故そのようなことをしたいかのシナリオを含め全体的にやりたいことを書いていただけると、別の提案ができるかもしれません。

    あと、質問の際には、最初にご自分の環境(OS, IIS, .NET のバージョン、使っているブラウザなど)を書いてください。

    • 回答としてマーク yana_tak 2014年6月19日 3:10
    2014年6月19日 2:39

すべての返信

  • Hoshinaです
    こんにちは

    やりたい事がよく分かっていない可能性がありますが,aspxではなくashxを使用することで解決しませんか?

    新しい項目の追加で選択できるものを順に確認して,拡張子が「ashx」のものを選択してみてください。

    それでは

    • 回答としてマーク yana_tak 2014年6月19日 2:47
    2014年6月19日 1:55
  • このケースに適合するかわかりませんが、Response.End()はダメでしょうか? ただし、このメソッドは例外を発生させますので、以下のように握りつぶさないとダメなような気がしますが・・・

    try
    {
        Response.End();
    }
    catch
    {
    }


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク yana_tak 2014年6月19日 2:47
    2014年6月19日 2:05
    モデレータ
  • 何故そのようなことをする必要があるのかの議論はちょっと置いといて・・・(他にやり方があると思われ)

    > 現在、ブラウザで確認すると、上記処理で出力した内容の後に、Default.aspxで定義
    > している内容が出力されています。

    デフォルトで作ると Default.aspx には <!DOCTYPE ... で始まる html コードが含まれるはずですが、サーバーはそれもクライアントに送信してから終了します。

    Response.Write("<html>・・・</html>"); のあと <!DOCTYPE ... で始まる html コードが送信されないようにするには、他の回答者の方の回答とダブりますが、以下の方法があります。

    (1) Response.Write("<html>・・・</html>"); の直後に Response.End(); として強制終了する。

    (2) <!DOCTYPE ... で始まる html コードを全て削除する。

    (3) .aspx ページを使うのは止めてジェネリック HTTP ハンドラ (.ashx) を使う。

    お勧めは (3) です。

    局所的な部分の質問だけでなく、何故そのようなことをしたいかのシナリオを含め全体的にやりたいことを書いていただけると、別の提案ができるかもしれません。

    あと、質問の際には、最初にご自分の環境(OS, IIS, .NET のバージョン、使っているブラウザなど)を書いてください。

    • 回答としてマーク yana_tak 2014年6月19日 3:10
    2014年6月19日 2:39
  • Hoshinaさん

    回答ありがとうございます。画面を(ボタン等のUI)を必要としない場合は、ashxの方が向いているようですね。

    利用を検討してみます。

    2014年6月19日 2:40
  • trapemiyaさん

    Response.Write()の実行後に、Response.End()を実行することで、目的を達成することができました。

    MSDNの説明を読むと、CompleteRequestを呼ぶ方が良いのでしょうか・・・?

    もう少し調査が必要そうですが、ひとまずはこれにて解決といたします。

    ご回答、ありがとうございました。

    2014年6月19日 2:47
  • SurferOnWwwさん

    環境について記載しておらず、申し訳ありませんでした。以後気をつけます。私の環境は、Windows Server 2012 R2、.NET 3.5となります。

    既存のページ遷移に割り込むようなページとなり、POST/GETで飛んできた値をそっくりそのまま次のページに渡すことをしています。その処理(Form要素やinput要素の動的生成)をDefault.aspx.cs内のループ処理で実現しています。そのときにhtml全体を作成しているので.aspxの内容は不要となっています。

    ※固定部分は.aspxで定義し、動的に生成する部分(Input要素など)を.aspx.csで定義したうえで.aspxにはめ込むのが正しいのでしょうが、現在は実験的に作っているページであることと、私がASP.NETに不慣れなためにhtml全体を.aspx.csで作った方が早いため、このような作りになっています…。

    trapemiyaさんの回答にもあったように、とりあえずは(1)で解決はしたのですが、本来は(3)(もっと言うと、前述の通り.aspxでの出力は止める必要が無い)ということですね。

    いろいろと勉強になりました。ありがとうございました。

    2014年6月19日 3:10
  • >MSDNの説明を読むと、CompleteRequestを呼ぶ方が良いのでしょうか・・・?

    このメソッドを恥ずかしながら私は初めて見たような気がするのですが(すみません)、調べてみるとこちらは例外が発生しないので、こちらの方が良いかもしれませんね。ただし、こちらはOnEndRequestに制御が移り、以降のコードは実行されるようです。

    (参考)
    ASP.NET コード内で別ページにリダイレクトする場合の留意点
    http://program.station.ez-net.jp/special/asp.net/basis/redirect.asp


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年6月19日 4:38
    モデレータ
  • このケースに適合するかわかりませんが、Response.End()はダメでしょうか? ただし、このメソッドは例外を発生させますので、以下のように握りつぶさないとダメなような気がしますが・・・

    try
    {
        Response.End();
    }
    catch
    {
    }

    一応補足ですが、この例外はキャッチする必要はありません。
    というか、キャッチしても勝手に再スローされますので、無駄になります(実態はThreadAbortExceptionなので)。

    Response.Endを避ける方が良いといわれるのは、この例外をスローするためパフォーマンス上のペナルティがそれなりにあるためです。
    例外のペナルティはキャッチする際が大きいので、キャッチすると余計害が大きくなります。

    とはいえ、このパフォーマンスペナルティも程度問題ですので、他の処理で非常に重いのにこれだけを避けることには、あまり意味はありません。

    Redirectでも(普通にやれば)同様に例外が発生してパフォーマンスロスがありますが、まあ大抵はそこまで気にせず使いますよね。

    なので、まあ必要であれば使えばよいです(極端に避ける必要はありません)。

    ※ちなみにこれらのResponse.Endによる例外は、通常はスローされる時点のスタックが浅いですので、パフォーマンスロスは比較的軽いです。

    もちろん今回のような場合は、みなさん書かれているようにashxが妥当ですし、そちらをおすすめします。

    --追記

    こう書きましたけど、最後に書かれたやりたかったことのイメージが微妙によく理解できなかったので、「もちろん今回のような場合はashxが妥当」なのかはちょっとなんとも言えなくなりました…

    • 編集済み なちゃ 2014年6月19日 4:50
    2014年6月19日 4:44
  • 一応補足ですが、この例外はキャッチする必要はありません。
    というか、キャッチしても勝手に再スローされますので、無駄になります(実態はThreadAbortExceptionなので)。

    あ~、なるほどです。気付いていませんでした。
    フォローに感謝いたします。ありがとうございました。

    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2014年6月19日 5:12
    モデレータ
  • > 既存のページ遷移に割り込むようなページとなり、POST/GETで飛んできた値をそっくり
    > そのまま次のページに渡すことをしています。その処理(Form要素やinput要素の動的生
    > 成)をDefault.aspx.cs内のループ処理で実現しています。そのときにhtml全体を作成し
    > ているので.aspxの内容は不要となっています。

    そのような方法を取らなくても、TextBox や Label などのサーバーコントロールを .aspx.cs のコードで動的に生成し、それを動的に Page に配置するという ASP.NET で普通に行う方法で可能だと思います。

    たぶん、質問者さんが上記の方法に不慣れで、それより C# のコードで文字列を組み立てて静的な html コードを作る方がご自分にとって簡単ということで、そのような手段を取られたのではないかと想像しています。

    その想像が当たっているとすれば、自分としては、上に書いた「サーバーコントロールを .aspx.cs のコードで動的に生成して、それを動的に Page に配置する」という方法をお勧めします。

    ステートレスな HTTP をステートフルにする機能、イベントドリブンなサーバー側プログラム、ユーザー入力の検証等数々の有用なライブラリ、知らないうちに恩恵に与っている ASP.NET 組み込みのセキュリティなどは、サーバーコントロール、ViewState、ポストバックなどの ASP.NET の仕組みによって実現されています。

    静的な html コードではそれらは実現できませんから。特にセキュリティ(一例下記参照)。

    ASP.NET の組み込み機能を活用し、Web 攻撃を回避する
    http://msdn.microsoft.com/ja-jp/library/ms972969.aspx

    2014年6月19日 6:03
  • >そのような方法を取らなくても、TextBox や Label などのサーバーコントロールを .aspx.cs のコードで
    >動的に生成し、それを動的に Page に配置するという ASP.NET で普通に行う方法で可能だと思います。

    ご想像の通りです。いまいちASP.NETを理解していませんので…。

    今日も少し調べて見ましたが、Javascrit等のDOMを扱うような感じで、各要素のオブジェクトを動的に作成し、最後に<body>オブジェクトの中に追加、という感じなのでしょうかね…。

    いろいろとアドバイス、ありがとうございました。

    2014年6月19日 13:08