ASP.NET WebFormページコンテンツ出力方式

5063 ワード

今回は「Web Formページでコンテンツを出力する方法」についてお話しします.これは実はとても古い話題です.本文の内容はASPにも応用できるからです.NET 1.1以上.しかし、この話題の適用範囲は広い.現在の最新のASPでも.NET MVCフレームワークは、デフォルトのビューエンジンが依然としてASPに基づいている.NET WebForm(Page,Control,MasterPageなど).さらに、ASP.NET MVCフレームワークの特性は、ページ上で「直接出力」されることが多い.そこで、この話題はASP.NET MVCアプリケーションでは重要である可能性がある.
ではASP.NET MVCの例を挙げましょう.もし、ページにPartial Viewを生成したら、私たちはこのようにすることができます.
 Html.RenderPartial("MyPartialView"); %>

しかし、前の記事では、ページでこのように使用できる文字列を返す新しい方法Partialを提案しました.
= Html.Partial("MyPartialView") %>

aspxページはPageクラスのサブクラスにコンパイルされます.このサブクラスの主な「機能」は、ベースクラスを上書きしたRenderメソッドです.
public class MyPage : Page
{
    protected override void Render(HtmlTextWriter writer)
    {
        ...
    }
}

私たちが普段aspxページで書いている多くのコンテンツは、実際にはwriterを操作するコードになります.例えばwriterを用いる.Writeメソッドはコンテンツを出力するか,writerをサブコントロールに渡すRenderメソッドはコンテンツを生成するために用いられる.では、上記の2つのページのタグはそれぞれどのようにwriterを操作しているのでしょうか.
= expression %>

まずタグです.タグには式が含まれているため、セミコロンで終わることはできません.式の内部のデータはwriterに直接書き込まれます.たとえば、次のようなタグがあります.
= DateTime.Now %>

コンパイル後、次のようになります.
writer.Write(DateTime.Now)

タグとは異なり、タグには「文」が含まれています.文は自然に複数の行があり、自然に各行の最後にセミコロンが必要です.これは私たちが普段C#コードを書くようにします.しかし、実際には、文の機能は「内容を出力する」ためではなく、「論理を制御する」ために使われています.たとえば、ページには次のようなコードが書かれています.
 Func<int, bool> odd = i => i % 2 != 0; %>

これは、Renderメソッド内でFunc委任のタイプであるローカル変数oddを宣言したことに相当します.このようなコードを作成すると、次のようになります.
 for (int i = 0; i < 10; i++) { %>
    <span>
        = i + 1 %>
    span>
 } %>

生成されたRenderメソッドには、次のものが含まれます.
for (int i = 0; i < 10; i++)
{
    writer.Write("");
    writer.Write(i + 1);
    writer.Write("");
}

ページに書かれた通常HTMLタグであれば、コンパイル後は通常文字列として扱われます.一部の友人は「クライアントコントロール」などについて話していますが、runat=「server」タグが1つの要素にない場合は、ASP.NETはそれらを普通の文字列として扱うだけで、「HTML要素」という概念はありません.もちろん、上記のコードは「意図」を表しており、実際にはコンパイル後のaspxページのスペースや改行などの文字も出力の内容に含まれています1.
では、論理を制御するための文が含まれている以上、出力を表すための文ではないのに、なぜさっきのコードのHtmlが含まれているのか.RenderPartialメソッドもページ内容を生成しますか?それはRenderPartialメソッドが現在のHttpContext.に直接向かうためである.Response.Outputに文字が書き込まれています.多くの友達がResponseをよく使っています.Writeでコンテンツを出力しますが、実はWriteメソッドの内部でOutputに出力します.
実際,我々のページでHtmlTextWriterを用いてコンテンツを出力しても,その内部にはOutputが露出したTextWriterがカプセル化されている.検証のために、コードにブレークポイントを設定し、Renderメソッドのwriterパラメータを観察することができます.通常の場合、writerを見つけることができます.InnerWriter属性はHttpWriterオブジェクトであり、これはTextWriterのサブクラスであり、ASPでもある.NETで定義されている内部タイプ.
これがASPです.NETページ出力の詳細.では、以下の2つの出力方式の違いは何でしょうか.
= "Hello World" %>
 Response.Write("Hello World"); %>

効果的に見ると、両者には何の違いもありません.しかし実際には前者はページのHtmlTextWriterオブジェクトを用いて出力が,後者はResponseに直接向かう.Outputに内容を出力します.この違いは重要ではないように見えますが、実際には多くの開発過程で利用できる実践方法に関連しています.今後の記事では、ページの内容を生成するためのガイドラインをいくつか提案し、その理由を説明し、ASP.NET MVC自体がこれらの設計基準をどのように破壊したのか.
自然、修正バージョンのASP.NET MVCはMvcPatchプロジェクトに公開されます.
 
注1:小城物語の同級生から注意され、厳密に言えば、ページの純テキストはLiteralコントロールとして処理され、連続した純テキストはLiteralコントロールとして処理されます.出力時にLiteralコントロールのRenderメソッドは、純テキストをHtmlTextWriterに出力します.その効果はwriterに等しい.Write(...)方式の純テキスト出力.