Microsoft ASP.NET 2.0 に向けての Web アプリケーションの再構築

Dino Esposito
Wintellect

June 2004

適用対象:
   Microsoft ASP.NET 1.1
   Microsoft ASP.NET 2.0

概要: ASP.NET 2.0 では ASP.NET 1.1 との下位互換性が完全に確保されていますが、一部の新機能を利用するためには Web アプリケーションの部分的な手直しが必要になる場合もあります。 ここでは、ASP.NET 2.0 で加えられた変更が移植の決定に与える影響について詳しく分析します。

目次

ASP.NET アプリケーションのデザイン
プロバイダ モデル
ページのプロトタイピング
ページの作成
データ連結の強化
アプリケーション サービス
結論
参考書籍

Microsoft ASP.NET は、急速に成長している強力な Web 開発プラットフォームであり、 世界最大級の Web サイトや最も要求の厳しいアプリケーションに利用されています。 Microsoft .NET プラットフォームの一部となる ASP.NET には、拡張性が高く使いやすいコンポーネントベースのツールが用意されており、これらのツールを使用して、さまざまなブラウザやモバイル デバイスをターゲットとする Web アプリケーションを構築、配置、および実行できます。 登場から 2 年以上が経った現在、ASP.NET は既に数千人の開発者に採用されています。 そしていよいよ、初めてのメジャー アップグレードとなる ASP.NET 2.0 (これまでは "Whidbey" というコードネームで呼ばれていました) が公開されました。

ASP.NET 2.0 (現在はベータ バージョンが公開されています) では、ASP.NET の現行バージョンとの下位互換性が 100 パーセント確保されているため、リリース後の移行もスムーズです。 下位互換性が確保されているということは、既存のすべての ASP.NET 1.x コードが ASP.NET 2.0 でも正常に動作するということです。 しかし、ただバージョンを切り替えただけで ASP.NET 2.0 フレームワークを最大限に活用できるとは限りません。 ASP.NET 2.0 の新機能の利用により、よりコンパクトなコード、より豊富なサービスと機能、より効果的かつ魅力的なユーザー インターフェイス、より洗練された保守の容易なアプリケーション アーキテクチャ、一連の強力な管理ツールを保証します。

ここでは、既存の ASP.NET アプリケーションを移行するにあたって考慮する必要がある ASP.NET 2.0 の機能の概要を、注釈を交えつつ紹介します。

ASP.NET アプリケーションのデザイン

現実の Web アプリケーション、とりわけ ASP.NET アプリケーションのほとんどは、次の図のようなスキームに従っています。

Dd314315.rearchitectv20-01(ja-jp,MSDN.10).gif

図 1. Web アプリケーションのプレゼンテーション層は、システム サービス (セキュリティ、パーソナライゼーション、状態管理など) とのやり取りを通じてビジネス ロジック層やデータ層に接続します。

ASP.NET 1.x アプリケーションでは、プレゼンテーション層が一連のシステム サービス (状態管理、セキュリティ関連の機能、サイト ナビゲーション、サイト カウンタなど) とやり取りします。 ページはリテラルとサーバー コントロールの集合であり、ページやコントロールのイベントを処理するためのグルー コードが大量に含まれています。

ページの実際の動作は、ページの背後で実行されるコードの層によって決まります。 比較的高度なアプリケーションでは、問題領域の処理のためにビジネス ロジック層 (BLL) が用いられます。 データ アクセスやデータの格納が必要な場合は、また別の層 (データ アクセス層 (DAL)) が加わります。 さらに、エンタープライズ サービスや相互運用性サービスとのやり取りが必要な場合は、Web サービスや COM+ 拡張が含まれます。

既存アプリケーションの BLL や DAL は、ASP.NET 2.0 における機能の変更や強化によって直接の影響を受けることはありません。 ただし、ジェネリクス、パーシャル クラス、ADO.NET 2.0、.NET リモート処理、そして将来的には "Indigo" など、.NET Framework 2.0 の強化された機能をこれらの層で活用することもできます。 その一方で、ASP.NET 2.0 アプリケーションでは、ASP.NET 1.x アプリケーションに構築した既存の BLL や DAL を簡単に再利用できます。 また、ADO.NET 2.0 と SQL Server 2005 の間のより緊密な統合を活用することによって、DAL をさらに強化することもできます。

既存のアプリケーションに影響を与える可能性がある ASP.NET 2.0 の主な変更のほとんどは、プレゼンテーション層 (ページやコントロールがある層) の中やその周辺の機能に関するものです。 図 1 に示したシステム サービスは、ほとんどのアプリケーションで必要となるものですが、中には ASP.NET 1.x によってネイティブで提供されていないものもあります。 具体的に言うと、図 1 で背景が白くなっているサービスは、ASP.NET 1.x アプリケーションではサードパーティ ツールや手書きのコードを通じて提供されていました。 このように独自に作成したサービスについては、ASP.NET 2.0 の新機能の観点から設計や実装を見直すことができます。

図 1 の "データ ブリッジ" ブロックによって示される層のコードは、多くの場合、ASP.NET ページの分離コード クラスに埋め込まれます。 このコードはポストバック イベントを処理し、BLL オブジェクトへの呼び出しを準備します。 より単純なケースでは、DAL とデータ連結コントロールの間の連結を準備します。 ここで簡単な例を見てみましょう。

DataGrid コントロールを持つ Web ページがあったとします。 グリッドの内容のページング、並べ替え、および編集を行うには、多くのコードが必要になります。 通常このコードでは、ASP.NET キャッシュとのやり取りやクエリの実行が行われるほか、insert ステートメントや update ステートメントを準備するためにページ コントロールからのデータの取得も行われます。 このコードはすべてページの背後で実行され、通常は、分離コード クラスか、データ連結コントロールを BLL や DAL に連結するヘルパ コンポーネントに埋め込まれます (後者がより望ましい)。 ASP.NET 1.x では、定型コードが 8 割を占めるこのコードをすべて手作業で記述しなければなりません。

要するに、図 1 のようなデザインのアプリケーションがあった場合、ASP.NET 2.0 では少なくとも次の 4 つの領域で大きなメリットがあります。

  • すばやく効果的なページのプロトタイピング。ポータル アプリケーションのデザインと実装を大幅に単純化する、状況に応じたサポートが提供されます。
  • さまざまな新しいコントロール (場合によってはブラウザの機能を徹底的に活用する) によって実現される、すばやく効果的なページの実装。 TreeViewMenuWizard などのコントロールや、セキュリティ関連のコントロール (LoginLoginStatusChangePassword) を使用することにより、ページをスリム化し、開発者の作業をできる限り少なくすることができます。
  • 機能豊富なデータ連結コントロールとスキームの下方に位置するその他の層 (BLL や DAL) の間を仲介する、コンパクトで洗練された生産性の高いデータ ソース クラス。 なお、ASP.NET 2.0 では双方向のデータ連結も実現されています (図 1 のデータ連結の矢印が双方向になっているのはこのためです)。
  • ユーザーとロールの管理、サイト ナビゲーション、サイト カウンタ、管理ツール、パーソナライゼーション、テーマなど、アプリケーションに合わせて作られた新しいサービス。 状態管理やセキュリティなどの既存サービスも強化されており、場合によっては、まったく新しい機能 (カスタム セッション ストア、カスタム キャッシュ依存関係、Cookie を使用しない認証など) も追加されています。

さらに、ASP.NET 2.0 インフラストラクチャの大部分で、いわゆるプロバイダ モデル (英語) が活用されています。 プロバイダ モデルは、それ自体でアプリケーションの機能や速度、即応性などを高めるわけではありません。 つまり、ユーザーや開発者が実際にやり取りできるような "目に見える" 機能ではなく、 アプリケーションのアーキテクチャを改善し、高度なカスタマイズを可能にするインフラストラクチャ機能です。

プロバイダ モデル

"プロバイダ" は、既存のシステム機能を拡張したり完全に置き換えたりするプラグ可能なコンポーネントとして定義されます。 つまり、プロバイダ モデルを利用することにより、API (ユーザーのメンバシップ、セッションの状態管理、パーソナライゼーション、サイト ナビゲーションなど) の既定の実装をプラグアウトし、独自の実装をプラグインすることができます。 プロバイダ モデルをサポートする特定のシステム機能のプロバイダを独自に記述することによって、トップ レベルのインターフェイスはそのままに、基となる実装、データ形式、記憶媒体などを変更することができます。

プロバイダ モデルが ASP.NET 2.0 プラットフォームの重要な要素となっているのは、それによってコードの再利用が大幅に促進されるからでもあります。

たとえば、Active Directory ベースの API を使ってユーザーやロールを管理するアプリケーションがあったとします。 そのカスタム API を実装するためには多くのお金と労力が費やされているため、ASP.NET 2.0 にメンバシップとロール管理の API が備わっているからといって、簡単に捨てられるものではありません。 しかしその一方で、洗練された新しいシステム API にも捨てがたい魅力があります。 以下にそのほんの一例を紹介します。


// 指定されたユーザーを認証します。
if (Membership.ValidateUser(user, pswd))
{...}

// 新しいユーザーを作成します。
Membership.CreateUser(user, pswd);

// ユーザー情報を取得します。
MembershipUser user = Membership.GetUser(user);

Membership クラスは、ユーザー管理のための中央コンソールに相当します。 ただし、このクラスの静的メソッドは機能を実装しておらず、実装は個々のプロバイダに任されています (次の擬似コードを参照)。


// 現在のプロバイダがユーザー認証を行います。
static bool ValidateUser(string username, string password) 
{
   // プロバイダは、web.config で定義されているクラスのインスタンスです。
   return Membership.Provider.ValidateUser(username, password);
}

結論としては、Active Directory をベースとするカスタム メンバシップ プロバイダを記述することができます。 これにより、既存のコードを簡単かつ効果的に再利用できます。 そのためには、MembershipProvider 基本クラスから継承した新しいプロバイダ クラスでコードをラップするだけです。 作成したクラスは、web.config のエントリを通じて、ASP.NET 2.0 の組み込みのメンバシップ インフラストラクチャに関連付けることができます。

Active Directory (Application Mode) をベースとする ASP.NET 2.0 メンバシップ サービスのカスタム プロバイダを作成する方法については、「ASP.NET 2.0 のメンバシップのためのカスタム プロバイダの作成」を参照してください。

プロバイダ モデルは、メンバシップ、ロール管理、パーソナライゼーション、サイト ナビゲーションなど、ASP.NET 2.0 インフラストラクチャのさまざまな側面で利用できます。 各プロバイダはそれぞれ独立した機能を表しますが、複数のプロバイダを組み合わせて新しいより強力なサービスをサイトに提供することもできます。 さらに重要な点として、既存の ASP.NET 1.x コードをラップして、こうしたサービスの中核コードに含めることができます。

要するに、ASP.NET 1.x には、次のような一般的なアプリケーション機能に対応するコンポーネントが組み込まれていませんでした。

  • ユーザー管理 (メンバシップ)
  • ロール管理
  • ユーザー プロファイル (パーソナライゼーション)
  • サイト ナビゲーション

このため、開発者はこれらの機能をゼロから構築しなければなりませんでした。 一方、ASP.NET 2.0 にはこれらの機能の API が組み込まれています。 このため、開発者はこれらの機能をゼロから構築しなければなりませんでした。 一方、ASP.NET 2.0 にはこれらの機能の API が組み込まれています。 この新しい組み込みの API を利用して同じタスクを実現するには、既存のコードを捨てなければならないのでしょうか。 必ずしもそうではありません。 プロバイダ モデルを利用すれば、既存の API を、ASP.NET 2.0 の新しいトップレベルのプログラミング インターフェイスと統合できます。これには二重のメリットがあります。 つまり、既存のコードを再利用できるうえ、共通の優れたプログラミング インターフェイスも使用できます。

プロバイダ モデルは、ASP.NET プログラミング モデル全体に対するインフラストラクチャ上の重要な改良と言えますが、必ずしも既存のアプリケーション (その多くは、既にメンバシップ、パーソナライゼーション、ナビゲーションなどの独自の API を備えている) を強化するものではありません。 そうではなく、既存のコードの再利用を可能にし、将来のシームレスな変更のためにアプリケーションをより柔軟かつオープンにするためのものです。

次に、既存のアプリケーションを改良したり、新しいアプリケーションをよりすばやく効果的に作成したりするのに役立つ、ASP.NET 2.0 のその他の機能について見てみましょう。

ページのプロトタイピング

ASP.NET 開発者からの質問によくあるのが、大規模なアプリケーションで似たような外観を持つページを大量に作成するにはどうすればよいか、というものです。 似たような外観のページとは、同じレイアウトを共有し、多くの UI ブロックを再利用するページのことです。 こうしたページは、すばやく簡単に、またできれば動的に、作成できるようにする必要があります。また、保守や更新も容易でなければなりません。

数年前、まだ ASP の時代の頃に、あるクライアントが、サイトも間もなく完成という頃になって企業のロゴを変更してきました。 あの悪夢のような出来事は今も忘れられません。 \images フォルダのファイルを 1 つ差し替えれば済むことではないか、と思われるかもしれませんが、 それで済む場合ばかりではありません。 このとき渡されたのは、別の配色を使ったよりサイズの大きいイメージでした。 結局、各ページで必要となる修正はわずかなものでしたが、修正しなければならないページは 500 ページ以上に及びました。 そのときはサーバー側インクルード (SSI) を使用していましたが、たいした助けにはなりませんでした。

一貫したレイアウトは、サイトの複雑さに関係なく、最先端の Web サイトに共通の特徴となっています。 ヘッダーおよびフッターと本文から成るレイアウトを持つ Web サイトもあれば、メニュー、ボタン、およびパネル (実際のコンテンツが配置され、表示される) の集合から成るより洗練されたレイアウトを持つ Web サイトもあります。 こうした Web サイトを構築するには、どうすればよいのでしょうか。

この種の問題には、古典的な ASP でも ASP.NET 1.x でも対応できますが、いずれもこうしたシナリオに真っ向から取り組んではおらず、決定的かつ最適なソリューションを提供するには至っていません。 これに対して ASP.NET 2.0 は、新しい技術となる "マスタ ページ" によって、この問題に正面から取り組んでいます。基本的には、"スーパーテンプレート" をユーザー定義のコンテンツと結合する ASP.NET Framework の 機能が活用されています。 ** ASP.NET 1.x で Web サイトのすべてのページに共通のレイアウトを適用するには、共通のユーザー インターフェイス ウィジェットをすべてユーザー コントロールでラップし、それらをすべてのページで再利用します。 古典的な ASP では、インクルード ファイルが最良のアプローチとなります。

アーキテクチャの観点から言えば、ユーザー コントロールを使用したソリューションでも特に問題はありません。 しかし、実際問題としては、大規模なアプリケーションに対しては管理しやすいモデルとは言えません。このモデルの有効性は、アプリケーションの複雑さ (含まれるページの数) が増すにつれて低下します。 サイトに数百ものページが含まれるような場合にユーザー コントロールで共通の要素を処理しようとすると、すぐに効率が低下して、収拾がつかなくなってしまいます。

このモデルでは、コンテンツ ページに重複するコードが含まれることになります。 実際、すべてのページでユーザー コントロールを参照する必要があるため、ページのデザインやユーザー コントロールのプログラミング インターフェイスになんらかの変更を加えるたびに、すべてのページを更新 (および再コンパイル) しなければなりません。 毎回数百ものファイルに手を加えるのでは話になりません。これが、この方法が決定的なソリューションにならない理由です。

マスタ ページ

ASP.NET 2.0 では、マスタ ページによってページのプロトタイピングが大幅に簡単かつ効果的なものになっています。 マスタ ページを使用することにより、次のようなことが可能になります。

  • 個々のコンテンツ ページが明示的に参照するスーパーテンプレート (マスタ ページ) を定義する。
  • Web 領域のすべてのページ、ディレクトリ内のすべてのページ、または個々のページにマスタ ページを割り当てる。
  • アプリケーションで複数のマスタ ページをサポートする。
  • マスタ ページとコンテンツ ページの両方で WYSIWYG がサポートされる。

マスタ ページとは、依存するすべてのページのテンプレートを定義する単一のページです。 通常の .aspx ページと同様に、マスタ ページには、それぞれ固有の ID で区別される置き換え可能なセクションが含まれています。 @Page ディレクティブでマスタ ページを参照するアプリケーションのページは、マスタ ページで定義されている構造を継承します。 マスタ ページをベースとするページは、"コンテンツ ページ" と呼ばれます。 ** 1 つのマスタ ページを複数のコンテンツ ページに関連付けることができます。

マスタ ページは、エンド ユーザーからはまったく見えません。 ユーザーがアプリケーションで作業する際に表示されたりユーザーが呼び出したりするのは、コンテンツ ページの URL だけです。 コンテンツ ページが要求されると、ASP.NET ランタイムは、状況に応じたコンパイル アルゴリズムを適用し、マスタ ページとコンテンツ ページを結合して動的ページ クラスを構築します。 次の図は、全体のしくみを表しています。

Dd314315.rearchitectv20-02(ja-jp,MSDN.10).gif

図 2. 1 つ以上のコンテンツ プレースホルダを含むマスタ ページ。プレースホルダは、置き換え可能なコンテンツが表示される領域を定義します。

マスタ ページには、名前付きのコンテンツ プレースホルダが含まれています。実際のコンテンツは派生ページによって提供されます。 共有される情報は更新可能な単一の場所 (すなわちマスタ ページ) に格納されており、ASP.NET ランタイムによって、関連付けられているすべてのページに複製されます。

ASP.NET 2.0 では、マスタ ページが Web ページを構築する唯一の方法でも、好ましい方法というわけでもありません。 現在 UI 部分を複製するためにユーザー コントロールを多用している場合は、マスタ ページの利用を検討する必要があります。 マスタ ページを利用すると、ページの構築や保守を大幅に単純化できるだけでなく、プレゼンテーション層全体の構造の合理化にもつながります。

マスタ ページは必要に応じて入れ子にすることができるため、ページの階層を作成するためにも使用できます。このため、関連するページが数百に及ぶような大規模なアプリケーションでは理想的なアプローチとなります。 また、カスタム オブジェクト モデルを併用することにより、アプリケーション固有のページ コンポーネント (メニュー、ツールバー、ヘッダーなど) を派生コンテンツ ページに公開することもできます。

Web パーツ

アプリケーション (またはその一部) がポータルのような外観を持ち、個別に操作できる複数の情報ウィンドウで構成されている場合は、ASP.NET 2.0 Web Parts Framework (WPF) がすぐに役に立ちます。 Web パーツとは、ページ内で利用できる情報ウィンドウのようなものです。 このウィンドウは、SharePoint を使用して作成したアプリケーションの場合と同じように、閉じたり、最小化したり、元のサイズに戻したりできます。 Web パーツを後述のパーソナライゼーション API と組み合わせることによって、開発者は、個々のユーザーのニーズに合わせてカスタマイズされたページやコントロールを簡単に作成できます。エンド ユーザーは、それらにさらなるカスタマイズを加えることができます。 WPF は、ポータルを作成するための完全なフレームワークではありませんが、ユーザーが自由に表示できるオプションの情報ブロックを含むページを作成するための効果的なツールとなります。

ページの作成

ASP.NET 2.0 の最大の見所の 1 つがコードの削減です。 いくつかの一般的な開発シナリオでは、コードを 70 % も削減することができます。 どうしてそのようなことが可能なのでしょうか。 ASP.NET 2.0 には、先進のリッチ コントロールが数多く導入されています。これらは使い方も簡単で、コードを追加することなく一般的な操作を実行できます。 開発者が処理を宣言するだけで、その処理がすばやく、明確に、効果的に実行されます。

ASP.NET 2.0 のツールボックスには 50 以上の新しいコントロールが含まれており、その大半が、ウィザード、ツリー ビュー、メニュー、双方向のデータ連結などの高度な機能を提供するものです。 これらの新しいコントロールは、次のような領域に分類できます。

  • ログインとセキュリティ
  • データ ソース コンポーネント
  • データの連結
  • Web パーツ
  • ナビゲーション
  • リッチ UI
  • イメージ操作
  • モバイル

ログインおよびセキュリティ関連の一般的な操作のほとんどは、コントロールを通じて簡単かつ直接的に行えるようになりました。 たとえば Login コントロールは、現在選択されているメンバシップ プロバイダと自動的にやり取りして、ユーザーの資格情報を確認します。 また、LoginView コントロールは、現在のユーザーの名前を取得して、ログオンまたはログオフのリンクと共に表示します。 ユーザーやユーザーの資格情報を管理するためのページはこれまでになく簡単に構築できるようになっており、通常は 1 つか 2 つのコントロールを使用するだけで済みます。 ログイン コントロールをマスタ ページと組み合わせれば、ヘルパ ページの開発もあっという間です。 しかも、結果となるページにはコードがほとんど含まれず、周囲のユーザー インターフェイスのほとんどは、関連付けられているマスタ ページから提供されます。 このページの保守は、問題になるどころかむしろ楽しみです。 また、プロバイダ モデルによって、ログインやセキュリティの機能のためにこれまでに記述したカスタム コードも再利用できます。たとえ ASP.NET 2.0 ソリューションで一連の新しいコントロールが利用されていても、既存のコードを問題なく適合させることができます。

サイト ナビゲーション

サイト ナビゲーションでもプロバイダ モデルを活用できます。 既定では、サイト マップはある特定のスキーマを持つ XML ファイルで定義されていなければなりません。 では、サイトの情報が既に別の場所に別の形式で格納されている場合はどうすればよいのでしょうか。 そのような場合も、カスタム サイト マップ プロバイダを記述するだけで、サイトマップの共通の API を通じて情報を公開することができます。 これにより、アプリケーションの構造やインフラストラクチャを変更することなく、新しい ASP.NET 2.0 の API を活用できます。 このほか、ASP.NET 2.0 では、現在表示されているページへのパスを表示する新しい UI コントロールも用意されています。 さらに、サイト マップの情報 (形式や記憶域メディアは問いません) を、TreeViewMenu などの階層コントロールに関連付けることもできます。

テーマ

テーマは、アプリケーションのパーソナライゼーション層を強化する ASP.NET 2.0 の新機能です。 テーマは CSS ファイルの強化版のようなもので、ページ内のすべてのカスタマイズ可能な要素のすべての視覚スタイルを統一します。 テーマは名前で識別され、CSS ファイル、イメージ、およびコントロール スキンによって構成されます。 コントロール スキンとは、既定のコントロール宣言を含むテキスト ファイルで、コントロールの視覚プロパティが設定されています。 この機能が有効な場合に、たとえば DataGrid コントロールをページに追加すると、テーマで定義されている既定の外観を使ってそのコントロールが表示されます。

Visual Studio 2005 のツールボックス

次の図は、Visual Studio 2005 で表示される ASP.NET 2.0 のツールボックスを示しています。 タブの数が大幅に増えていますが、それは、コントロールがより細かく分類されるようになったためだけではありません。

Dd314315.rearchitectv20-03(ja-jp,MSDN.10).gif

図 3. ASP.NET 2.0 のツールボックス

ASP.NET 2.0 では、より強力かつ機能豊富なコントロールと、Visual Studio 2005 のデザイナに組み込まれた新機能によって、必要となるコードが大幅に減っており、ページを簡単に作成できます。

データ連結の強化

データ連結コントロールは、ASP.NET 1.x アプリケーションでも既に十分効果的なものとなっていましたが、 それでも、実際に求められるレベルには達していませんでした。 特に、並べ替えやページングだけでなく、コントロールに連結されたコンテンツの編集のときでさえ、ASP.NET 1.1 には、データの取得に利用できる高レベルなモデル (宣言型のモデル) がありませんでした。 その結果、ASP.NET 1.x のデータ連結層は、比較的単純な作業を行うのにも数百行ものコードを書かなければならない面倒なものとなっていました。

ASP.NET 1.x アプリケーションの開発者は、プレゼンテーション層と BLL や DAL とを仲介するコード (図 1 の "データ ブリッジ" ブロック) を手作業で記述しなければなりません。 ASP.NET 2.0 のデータ ソース モデルはこの問題に対処しており、 データ連結のメカニズムを単純化するために、"データ ソース コンポーネント" と呼ばれる一連の新しいデータ コンポーネントがデータ連結コントロールによってサポートされています。このデータ ソース コンポーネントが、宣言型の連結モデルをサポートします。 **

ASP.NET 2.0 では、データ連結コントロールを IEnumerable ベースのオブジェクトに連結する代わりに (ASP.NET 1.x ではこの方法しかありません)、データ ソース コンポーネントと呼ばれる別のサーバー コントロールに連結します。 データ ソース コンポーネントには、実際のデータ ソースとの間に直接の双方向のリンクがあります。データ ソースは、SQL データベースでも、XML でも、さらにはカスタム BLL でもかまいません。

データ ソース コンポーネント

データ ソース コンポーネントは、SelectInsertDeleteUpdateSortCount など、データ ソースに対して主な操作を実行する、よく知られた一連のメソッドを公開します。 これにより、データ連結グリッド コントロールで、呼び出し元ページに対してイベントを発生させたりカスタム コードを記述したりすることなく、表示されるデータの並べ替え、ページング、編集を行うことができます。 たとえば、バージョン 1.xDataGrid は、特定のレコードに加えた変更をユーザーが保存するたびに、UpdateCommand イベントを発生させます。 DataGrid は、表示するデータの背後にある実際のデータ ソースについては何も知りません。 ただ、実際のソースから完全に切断されたメモリ内のデータ コンテナを参照しているだけです。 その後には、接続を開き、コマンドを発行し、グリッドを更新するための追加のコードが必要になります。 このコードは手作業で記述しなければなりません。 現在、ほとんどの ASP.NET 1.x アプリケーションにこのコードが埋め込まれています (特殊なバージョンの DataGrid コントロールに埋め込まれている場合もあります)。

ASP.NET 2.0 では、GridView コントロール (好評な DataGrid コントロールの後継) を中心とする一連の新しいデータ連結コントロールが導入されています。 ほかに、TreeViewFormViewDetailsView などがあります。 GridView では、DataGrid と同様の機能が用意されているほか、さまざまな機能の拡張と強化が行われています。 中でも注目すべきは、データ ソース コントロールとの連携の機能です。 新しい DataSourceId プロパティを通じて GridView をデータ ソース コントロールに連結できます。

ASP.NET 2.0 では、GridViewDataGrid の両方のコントロールで DataSourceId プロパティがサポートされているので注意してください。 両者の違いは、コントロールのコードとデータ ソース コントロールとの統合のレベルにあります。 ASP.NET 2.0 の DataGrid は、データ ソース コントロールの Select の機能のみを使用します。 表示するコンテンツのページング、並べ替え、編集の際には通常のイベントが発生するため、必要な動作のためのコードを記述できます。 これは明らかに、既存のコードを使用できるようにするための処置です。 一方、GridView コントロールははるかに先を行っており、データ ソース コントロールの機能をフルに活用して、ほとんどのグリッド イベントに定義済みの動作を割り当てることができます (下の図を参照)。

Dd314315.rearchitectv20-04(ja-jp,MSDN.10).gif

図 4. GridView とデータ ソース コントロールの間のやり取り

ユーザーが特定のレコードに新しい値を入力して保存した場合、GridView では、呼び出し元で処理される汎用のイベントは発生しません。 代わりに、連結先のデータ ソース コントロールの Update メソッドが呼び出されます。 この呼び出しは、データ ソース コントロールによってデータ ストア固有のコマンドに変換されます。その際には、宣言によって設定された接続文字列とコマンド プロパティが使用されます。 以下に例を示します。


<asp:sqldatasource runat="server" id="MySource" 
   connectionstring="SERVER=...;DATABASE=...;UID=...;"
   selectcommand="SELECT employeeid, firstname, lastname 
                  FROM employees"
   updatecommand="UPDATE employees SET
                  firstname=@firstname, lastname=@lastname 
                  WHERE employeeid=@employeeid">
</asp:sqldatasource>
<asp:gridview runat="server" id="MyGridView" datasourceid="MySource">
:
</asp:gridview>

前にも述べたように、ASP.NET 1.x アプリケーションには、プレゼンテーション層のデータ連結コントロールと BLL や DAL とを仲介するコードが既に含まれているのが一般的です。 この既存のコードと新しいモデルとを仲介するにはどうすればよいのでしょうか。

ASP.NET 2.0 には、SQL データ、プレーン XML ファイル、XML 形式のデータセットなど、さまざまな種類のデータ ソースに対応するさまざまなデータ ソース コンポーネントが用意されています。

なお、ここで言う "SQL データ" とは単にリレーショナル データのことであり、SQL Server や Oracle のデータベースから取得したデータとは限りません。 SqlDataSource コントロールを構成する際に、ConnectionString プロパティを使用して目的のデータ ソースを指定します。

ObjectDataSource クラス

ASP.NET 1.x のブリッジ コードを再利用するには、ほとんどの場合、ObjectDataSource クラスというまた別のデータ ソース コンポーネントが必要になります。 ObjectDataSource クラスを使用すると、ビジネス コンポーネントの内容をデータ連結コントロールに関連付けることができます。 このクラスは宣言型のパラメータをサポートしているため、開発者は、ページレベルの変数をオブジェクトのメソッドに渡すことができます。 これにより、ObjectDataSource クラスのインスタンスと一緒に使用できるクラスへとブリッジ コードを再構成できます。これで完了です。 既存コードのモジュール化の度合いによっては、ごくわずかな変更を加えるだけで済むこともあります。 ヘルパ コードがデータ連結コントロールに密接に結合されていればいるほど、必要な作業は多くなります。しかし、全体的に見てこの変更は決して無駄にはなりません。というのも、これによりコードのカプセル化とモジュール化が進み、ASP.NET 2.0 プラットフォームを最大限に活用できるようになるからです。

ObjectDataSource クラスでは、ラップするオブジェクトについていくつかの前提があります。 このため、任意のクラスと一緒に使用することはできません。 具体的には、既定のコンストラクタを持ち、ステートレスで、select、update、insert、および delete のセマンティクスに簡単にマップできるメソッドを持っていることが、連結可能なオブジェクトの前提になります。 また、一度に 1 つの項目を更新するように設計されている必要もあります。 要するに、ObjectDataSource で問題なく使用できるのは、このデータ ソース クラスを念頭において設計されたマネージ オブジェクトです。


<asp:ObjectDataSource runat="server" ID="MySource" 
     TypeName="App.MyBusinessObject" 
     SelectMethod="GetEmployees"
     UpdateMethod="SetEmployees">
     <UpdateParameters>
        :
     </UpdateParameters>
</asp:ObjectDataSource>
<asp:gridview runat="server" id="MyGridView" datasourceid="MySource">

上のコードは、ObjectDataSource オブジェクトを GridView と一緒に使用する方法を示しています。 MyBusinessObject クラスの GetEmployees メソッドは、表示するデータを取得します。SetEmployees メソッドは、適切なパラメータのセットを使って更新を実行します。 ASP.NET 1.x のロジックを移行して新しいクラスでラップすることができれば、より強力な新しいプログラミング モデルのコンテキストでそれを再利用できます。

データ連結については、注目に値するポイントがほかにもいくつかあります。 まず第 1 に、ASP.NET 2.0 のデータ連結は双方向です。つまり、データを元のソースに書き戻す機能も用意されています。 フィールドとコントロール プロパティの間の連結が双方向になっており、Bind という新しいキーワードが使用されます。

双方向のデータ連結

新しいキーワードの Bind は、Eval と同じ場所で、同じ構文で使用できます。


<asp:TextBox Runat="server" ID="TheNotes" 
     Text='<%# Bind("notes") %>' />

両者の最大の違いは、Bind は双方向 (読み取りと書き込みの両方) に機能するという点です。 たとえば、Text プロパティが設定されるときには、BindEval とまったく同じように動作します。 さらに、Text プロパティが読み取られる際には、Bind は値をコレクションに格納します。 有効なデータ連結コントロール (GridView コントロールのテンプレート列など) はこれらの値を自動的に取得し、それを使って、データ ソースに対して実行するコマンド (挿入や編集など) のパラメータ リストを作成します。 Bind に渡される引数は、コマンドのパラメータの名前に対応していなければなりません。 たとえば、上のテキスト ボックスは、@notes パラメータの値を提供します。 双方向のデータ連結は、ASP.NET 1.x には同等の機能がないまったく新しい機能です。 しかし、この機能を使用することによって、既存アプリケーションの一部の開発を大幅に単純化することができます。

複数フィールドによるインデックス

グリッドをベースとするアプリケーションでは、DataGrid コントロールや DataList コントロールによって公開される DataKeyField プロパティがよく必要になります。 DataKeyField には一意キー フィールドの名前が含まれています。ユーザーがクリック操作を行うと、コントロールはこのフィールドを使用して、選択された行のキー値を取得します。 このプロパティは、データ ソースの主キーが単一の列で構成されていることを前提としています。 では、行が列の組み合わせによって特定される場合はどうすればよいのでしょうか。

この制約は、メモリ内のデータ ソース (DataTable) に、実際にキーを構成する複数の列を連結する仮の列を追加することによって、簡単に回避できます。 しかし、ASP.NET 2.0 ではこのような方法を使用する必要もなくなりました。DataGrid の後継となる GridView コントロールによってサポートされている DataKeyNames プロパティでは、キー フィールドをカンマ区切りの文字列で指定できます。

アプリケーション サービス

ASP.NET 2.0 には、まったく新しいシステム サービスや大幅に強化されたシステム サービスが多数用意されており、それらをアプリケーションで利用できます。 新しいサービスには、パーソナライゼーション、サイト カウンタ、構成情報へのプログラムによる完全なアクセスなどがあります。 このほか、ユーザーとロールの定義、web.config ファイルの編集、ユーザー プロファイルの情報の有効化/無効化など、アプリケーションの管理のための新しいサーバー ツールも用意されています。 強化されたサービスには、セッションとキャッシュの管理やセキュリティなどがあります。 以下では、それぞれについて簡単に見ていきます。

パーソナライゼーション

パーソナライゼーション API では、使いやすいタイプ セーフな API を通じて構造化データを永続的に格納できます。 アプリケーションでパーソナライズ データの独自のモデルを定義すれば、後は ASP.NET ランタイムによって、そのモデルがクラスへと解析およびコンパイルされます。 パーソナライズ データの各メンバは、それぞれ現在のユーザーに固有の情報に対応します。 パーソナライズ データ (ユーザー プロファイル) の読み込みと保存は、エンド ユーザーからはまったく見えません。また、ページの開発者でさえ、その内部処理について詳しく知る必要はありません。 ユーザー プロファイルのレイアウトは構成ファイルで定義され、.NET の任意の型を取ることができるプロパティのリストによって構成されます。 データの格納は、ユーザーから見えないだけでなく、プログラマからもある程度見えなくなっています。 データの格納場所や格納方法についてユーザーが知る必要はなく、プログラマも、使用するパーソナライゼーション プロバイダの種類を指定するだけで済みます。 このパーソナライゼーション プロバイダによって、使用するデータベースが決まります。Microsoft Access や Microsoft SQL Server のデータベースを使用するのが一般的ですが、カスタム プロバイダとカスタム データ ストレージ モデルを使用することもできます (これもまた、プロバイダ モデルの実用上の利点の 1 つです)。 ユーザー プロファイル モデルは、<system.web> のすぐ下の <profile> 構成セクションで定義されます。 以下に例を示します。


<profile>
   <properties>
      <add name="BackColor" type="string" />
      <add name="ForeColor" type="string" />
      <add name="Height" type="int" />
      <add name="Width" type="int" />
   </properties>
</profile>

プロパティは、動的に作成およびコンパイルされるクラスにまとめられます。 その後、結果となるオブジェクトが現在の HttpContext オブジェクトに追加され、Profile プロパティを通じてページから利用できるようになります。 各インスタンスのプロパティ値は、パーソナライゼーション プロバイダ ソースから読み込まれ、そこに格納されます (既定のソースは、Data フォルダにある Access のデータベースです)。

サイト カウンタ

サイトの品質やコンテンツを改善するうえで、訪問者の利用状況を監視することは重要です。 Web サイトの利用状況を評価するメトリクスとしては、インプレッションとクリックスルーの 2 つがよく使用されます。 インプレッションは、ページや広告などの特定のコンテンツを表示することです。 クリックスルーは、特定のコンテンツを表示するためにユーザーが行うクリック操作です。 ASP.NET 2.0 には、ユーザーの利用状況 (特にインプレッションとクリックスルー) を追跡するための組み込みのカウンタがいくつか用意されています。

サイト カウンタ API は、状況に応じたプロバイダを通じて、カウント データや、データベースに対する書き込みや読み込みに関連するデータを収集します。 サーバー コントロールの開発者は、これらのカウンタのベースとなる API を使用して独自のカウンタを作成することもできます。 アプリケーションでカウンタ データを収集するには、組み込みのカウンタを有効にする方法と、直接サイト カウンタ API を使用してカウントを書き込む方法の 2 つの方法があります。この 2 つの方法を一緒に使用することもできます。 組み込みのカウンタには、ページ ビューのカウンタや、サーバー コントロール (HyperLinkAdRotator など) に対するクリックのカウンタなどがあります。 収集された情報はプロバイダに送信され、永続的なメディアに格納されます。SQL Server や Access のデータベースが使用されるのが一般的ですが、他の方法で格納することもできます。

サイト カウンタの情報は、後からプログラムによって収集することも、Web Administration ツールのレポートによって収集することもできます。 ここでもまた、プロバイダ モデルを使用することによって、バージョン 1.x のコードをラップして新しいアプリケーションで使用できます。

構成

ASP.NET 1.x では、ConfigurationSettings クラスを通じて構成情報にアクセスできます。 しかし、このクラスによって提供されるのは現在の設定の一部に対する読み取りアクセスのみであり、型指定も厳密ではありません。 さらに重要なことに、理論上はこのクラスを使用してあらゆる設定を読み取れることになっていますが、実際には、アプリケーション固有の設定やカスタム セクションに対してしか使用できません。

ASP.NET 2.0 では、定義済みのセクションごとに 1 つずつ、パブリックの構成クラスが用意されています。 各クラスは、プロパティを通じて構成ファイル (web.config と machine.config) の内容を公開します。 さらに、ASP.NET 2.0 では、構成ファイルをプログラムによって更新するためのツールも用意されており、前のバージョンのもう 1 つの問題も解決されています (更新は、書き込みの権限が与えられている場合に許可されます)。

セッション状態

セッション状態管理 API は、基となるアーキテクチャも含め、既に ASP.NET 1.x で大規模な変更が行われています。 セッション状態は、辞書ベースの API で構成されています。開発者はこれを使用して、セッションの間、ユーザー固有のデータを格納できます。 ASP.NET 1.x で、送られてきた要求を処理するために状態が取得される際には、まず組み込みの HTTP モジュールによって、現在のセッションの ID が取得されます (新しいセッションが開始される場合は、新しいセッションの ID が生成されます)。 続いて HTTP モジュールは、このセッション ID をキーとして使用して、物理記憶域メディア (メモリ、外部状態プロセス、SQL Server のテーブルなど) からそのセッションの内容を取得します。

ASP.NET 2.0 でもこの基本設計に変わりはありませんが、いくつかの側面が完全にカスタマイズできるようになっています。 このセッション状態の拡張モデルには、2 つの方法が用意されています。 ASP.NET の既存のセッション状態メカニズムの細部をカスタマイズする方法 (たとえば、Oracle セッション プロバイダを作成したり、ID の生成を制御するなど) と、標準のセッション状態 HTTP モジュールを新しいものに置き換える方法です。 前の方法は実装が容易ですが、カスタマイズできる機能が限られます。 後の方法では、コードがかなり複雑になりますが、最大限の柔軟性が約束されます。

セッション状態のデータ ストアを置き換えることができるというだけでも、多くの開発者にとって朗報となるはずです。これには、少なくとも 2 つの理由があります。 第 1 に、別のデータベース (Oracle や DB2 など) を使用していて、永続的なデータ ストアでしか実現できないような信頼性がセッション状態に求められる場合は、SQL Server をインストールしたり、学習したり、使用したりする必要がなくなります。 第 2 に (ここでもまたプロバイダ モデルが活用されています)、そのようなコードを既に開発してある場合は、それを標準のセッション管理エンジンに関連付けることができます。追加のコストも発生しません。

ここで補足として、セッション ID ジェネレータについても触れておきます。ASP.NET 1.x のセッション ID ジェネレータは、ハードコーディングされた変更不可能なコンポーネントでした。 ASP.NET 2.0 では、これを独自のものに置き換えることができます。つまり、独自のアルゴリズムを使ってセッション ID を生成できることになります。 乱数ジェネレータをベースとする Microsoft の標準のアルゴリズムが気に入らない場合や、信頼できないと思う場合は、代わりに独自のアルゴリズムを使用できます。 ただ、本当にその方が良いのかどうかをよく考えてみてください。 アプリケーションのセキュリティのレベルを大幅に低下させることにもなりかねません。

キャッシュ依存関係

Cache オブジェクトは、ASP.NET 1.x で追加されたすばらしい機能です。このオブジェクトは、バージョン 2.0 では一点を除いて更新されていません。 その唯一の変更となるのが、カスタム依存関係です。 Cache オブジェクトに新しい項目を追加する際には、項目の依存関係を定義して、一定の期間が経過するか、特定の時刻になるか、1 つ以上のファイルまたはキャッシュされた項目が変更されたら、キャッシュされた項目が削除されるようにすることができます。 ASP.NET 2.0 では、大きな目玉として、カスタム依存関係を作成できるようになりました。これにより、カスタム イベントが発生すると項目が無効になるようにすることができます。 たとえば、Web サービスのメソッドの戻り値が変わったらキャッシュされているデータを自動的に更新するキャッシュ依存関係オブジェクトを作成できます。

ASP.NET 1.x のキャッシュでは対応できない一般的なシナリオの 1 つが、データベースの依存関係です。 データベースの依存関係とは、カスタム依存関係の特殊な例であり、特定のデータベース テーブルの内容が変更されたらキャッシュされている項目を削除するというものです。 ASP.NET 2.0 には、SqlCacheDependency というクラスがこのために用意されています。このクラスは、SQL Server のテーブルに対する依存関係をサポートします (正確には、MSDE、SQL Server 7.0、およびさらに多くの機能をサポートしている SQL Server 2005 などのそれ以降のバージョンに対応しています)。

セキュリティ

ASP.NET のセキュリティの大部分は、コーディングのベスト プラクティスを実践することによって、攻撃対象となる要素を最小限に抑え、攻撃を簡単にかわすことができるようにすることが焦点となります。 たとえばデータ ソース コントロールでは、<parameter> タグが多用されています。 この単純な事実により、ASP.NET 2.0 アプリケーションに、SQL インジェクションやクロスサイト スクリプティングの危険を軽減する一般的なセキュリティ プラクティスが数多くハードコーディングされることになります。

セキュリティについてもう 1 つ注目すべき点は、構成ファイルにおける保護領域の使用です。 SDK のシステム ツールを使用することによって、web.config ファイルの重要な情報を含む箇所を簡単に暗号化できます。

以前のバージョンでは、ASP.NET のごく一部のセクションで、レジストリ キーや外部ユーティリティによるデータの保護がサポートされているだけでした。 ASP.NET 2.0 では、多くのセクションで暗号化が可能になっており、しかもそれを簡単に行えるようになっています。 セクションの内容を暗号化するには、web.config ファイルの <protectedData> セクションでセクションの名前を参照します。 これにより、指定したセクションが暗号化されていることが構成エンジンに伝えられます。 暗号化されたデータを実際に格納するには、aspnet_regiis.exe ユーティリティの最新バージョンを使用する必要があります。 データの暗号化には、XML Encryption 技術が使用されています。

サイトの機能へのアクセスを許可する前に行われるユーザーの資格情報の確認では、引き続きフォーム認証が中心になります。 ASP.NET 2.0 では、このモデルに改良が加えられて、メンバシップとロール管理のプロバイダが統合されています。 API を使用することによってより簡単かつ簡潔になるほか、Cookie を使用しない認証も導入されています。

ASP.NET 2.0 では、長く待ち望まれていた匿名 ID の機能も初めて導入されています。 これは、認証されていないユーザーに ID を割り当てるオプションの新機能です。 この機能が、要求を処理するアカウントの ID や、ユーザー ID やユーザー認証のその他の側面に影響を与えることはありません。 匿名ユーザー ID を有効にすると、認証されていないユーザーに一意の ID が割り当てられて、認証されていないユーザーを正式に認証されたユーザーと同じように扱うことができます。 これにより、認証されていないユーザーを追跡したり、パーソナライゼーションのプロパティを割り当てたりできるようになります。 匿名 ID が機能的に関連するのはパーソナライゼーションだけであり、メンバシップ サブシステムのその他の側面は一切変更されません。 割り当てられる一意の ID をプログラマがカスタマイズすることはできません。

匿名ユーザーの ID は、フォーム認証のチケットと同じように、Cookie に格納されます。 ただし、メンバシップ システムでは、匿名ユーザーはログインするものと見なされないので注意してください。 ユーザーのブラウザで Cookie が許可されていない場合は、要求されたページの URL に匿名 ID を埋め込むことができます。

結論

ASP.NET 2.0 には、より優れたアプリケーションをより早く作成するための新機能が豊富に盛り込まれています。 このため、2.0 への移行がほとんどの開発者に大きなメリットをもたらすことに間違いはありません。問題は、移行をスムーズに行えるかどうかです。

ASP.NET 2.0 の新機能の多くは、開発者のニーズや要望に直接応えたものとなっています。 これは、良いニュースであると同時に悪いニュースでもあります。 開発チームが開発者コミュニティの要求に耳を傾けて、開発者の生産性を高めるような環境の構築に取り組んでいる証拠と考えれば、良いニュースと言えます。 しかし、同じ理由から、悪いニュースとも言えます。 実際、ASP.NET 2.0 の機能が長く待ち望まれ、声高に要求されてきた機能だからこそ、一部の機能が既に開発者によって独自に実装されている可能性があると言えます。 それでは、2.0 への移行を問題なく効果的に行うためには、どのような手順を踏めばよいのでしょうか。

ASP.NET 2.0 で加えられた変更には、2 つの種類があります。 1 つは、既存のシステム機能をラップする高レベルのラッパー、もう 1 つは、HTTP パイプラインに対するより徹底的な変更です。 最初のグループに属するのは、パーソナライゼーション、テーマ、サイト カウンタ、キャッシュ依存関係、セキュリティ コントロール、リッチ コントロールなどです。これらの機能はいずれも、ASP.NET 1.x アプリケーションで実装するのもさほど困難ではありません。 MSDN Magazine の「Cutting Edge column archive (英語)」では、これらの機能の多くについて、実装例のコードやリンクを見つけることができます。 このように 1.x でも実現可能だからこそ、これらの機能は、既に実装されて実行されている可能性があります。 このようなシナリオにおいても移行するメリットはあるのでしょうか。 時間とお金を費やして開発したコードを捨て去るべきなのでしょうか。 また、おそらくさらに重要な問題として、システムのコンテキストやデータ モデルに完全に適合したコードを取り除く必要があるのでしょうか。

ASP.NET 2.0 の新機能の 2 つ目のグループには、アーキテクチャ上の変更に依存しているために 1.x のアプリケーションでは実装するのが不可能か、非常に困難なためコストを考えると現実的とは言えないような機能が含まれます。 たとえば、セッション データ ストアの変更、書き込み可能な構成、ここでは触れなかったクロスページ ポスティングなどの機能がこれに該当します。

この両極の中間に位置する機能もあります。これらの機能は、ASP.NET 1.x でも実装できますが、ASP.NET 2.0 の実際の実装ほど簡単かつスムーズなものにはなりません。 たとえば、 マスタ ページ、データ ソース コントロール、Web パーツ、匿名 ID などがこれに含まれます。

ASP.NET 2.0 では下位互換性が 100 パーセント確保されていますが、すべての新機能を活用するためには多少の再設計 (およびその後の問題の解決) が必要になります。 既存のコードを再利用するために不可欠となるプロバイダ モデル (新機能の中でもおそらく最高のもの) は、ただ再利用のチャンスを与えてくれるだけではありません。 プロバイダ モデルは、先ほどの問い、すなわち、ASP.NET 2.0 と同様の機能を実装するコードを捨てるべきかという問いに対する答えとなります。 そしてその答えはノーです。アプリケーションを再構成して、特定の機能のプロバイダに既存のコードをラップすることができます。 プロバイダ モデルは、コードの再利用と新しいプログラミング パラダイムへの完全な統合の両方を実現する、まさに一石二鳥の機能です。

その他の機能強化として、すぐに使用できるアプリケーションの付加的な機能があります。これらの機能は、ほかでは入手できないか、入手できたとしても不十分なものになります。 この種の機能強化の好例となるのがマスタ ページです。インターネットでは、マスタ ページの 1.x 実装のさまざまな例を見つけることができますが、 いずれも、実際のマスタ ページほどスムーズでシームレスなものにはなっていないようです。これは、実際のマスタ ページでは、API 全般と HTTP パイプラインに加えられた多少の機能強化が活用されているためです。

全体的に見て、ASP.NET 2.0 では開発生産性が大幅に向上しており、すべての開発者がリリース後すぐの移行を検討するだけの価値があります。 ASP.NET 2.0 でどのようなことが可能になるのかをざっと見ただけでは、既に作成してあるコードに置き換わるようなものも含め、あまりに多くの新機能が盛り込まれすぎていると思うかもしれません。 しかし、そう感じるのはきっと最初だけです。

この記事では、ASP.NET 2.0 の主な変更点を概観し、移行にあたっての問題を独自の観点から吟味しました。 ASP.NET 2.0 のすべての新機能を網羅するのではなく、アプリケーションを移植する際に影響がありそうな機能だけを取り上げました。 "移植" とは、アプリケーションが新しいプラットフォームで (設計によって保証されているとおりに) 動作すればそれでよいというものではありません。 ここで言う "移植" にはもっと深い意味があり、その目標は、新しい ASP.NET プラットフォームの強化されたパフォーマンスや開発環境を活用するために、アプリケーションの新しいバージョンを構築することです。

参考書籍