ScottGu's blog translated by Chica @ Wankuma

ASP.NET MVC Preview 4 リリース (パート 1)

  

ASP.NET MVC チームは"Preview 4" のリリースに向けて最終調整を行っており、今週末に出荷できればと思っているようです。Preview 3 リリースでは、コアのAPIの仕上げと、ASP.NET MVCの拡張性に焦点を当てていました。今週開始されたPreview 4では、コアな基盤上に構築された、さらに生産性を向上させるより高いレベルの機能が出現してきます。

今回のビルドでは新機能が数多く搭載されており、これらを全てカバーするために、ブログの投稿を2回に分けることにしました。今回の投稿では、Preview 4でのキャッシング、エラー処理、セキュリティなどの新機能、そしていくつかのテスト機能の改善点についてカバーします。次の投稿では、AJAXの新機能をカバーしたいと思います。

フィルタ インタセプタの理解

アクションフィルタ属性はASP.NET MVCで便利な拡張機能で、"Preview 2"で最初に追加されたものです。これらにより、MVCコントローラのリクエストへコードインタセプタを挿入することができ、これはコントローラもしくはそのアクションメソッドが実行される前後に実行することができます。

以下は非常に単純なフィルタ、"ScottGuLog" の例です。これはリクエストの実行中に発生した例外の詳細をログに残すために使用することができます。カスタムのフィルタクラスの実装は簡単です。"ActionFilterAttribute" タイプをサブクラス化し、適切なメソッドをオーバーライドするだけです。これにより、コントローラ上のアクションメソッドが起動される前後、またそのActionResult がリスポンスに対して処理される前後でコードを実行させます。

ASP.NET MVCコントローラでのフィルタ使用は簡単で、アクションメソッド上、もしくはコントローラクラス自身上(この場合コントローラ内の全てのアクションメソッドに適用されます。)で属性として宣言するだけです。

上記は2つのフィルタを適用した例です。"About" アクションメソッドへ"ScottGuLog"を適用し、"HandleError" フィルタをHomeController上の全てのアクションメソッドへ適用したいことを示しています。

前回のASP.NET MVCプレビューリリースでこのフィルタの拡張が可能になったのですが、プレビルドされたフィルタは出荷されませんでした。 ASP.NET Preview 4 では出力のキャッシング、エラー処理、セキュリティなどのケースを処理するために便利なフィルタがいくつか含まれています。

OutputCache フィルタ

[OutputCache]フィルタで、ASP.NET MVCとASP.NETの出力キャッシング機能を簡単に統合することができます。(これを行うには、ASP.NET MVC Preview 3 が必要です。)

お試しになるには、"Message" の値セットを、HomeController の "Index" アクションメソッド内で修正し、現在の時間を表示します。:

アプリケーションを実行すると、ページを更新する度に時刻も更新されていることが確認できます。

[OutputCache]属性をアクションメソッドに追加することで、このURLへ出力キャッシングすることができます。以下の様な宣言を使用して、10秒間の間リスポンスをキャッシュするように構成します。

現在ページ上で更新を押下すると、10秒毎でしか時刻が更新しないことが確認できます。これは、アクションメソッドが10秒に1回しか呼び出されないためです。この時間の間隔の間に発生するすべてのリクエストはASP.NETの出力キャッシュ外として見なされるのです。(つまりコードを実行する必要がないため、超高速となります。)

時間間隔のサポートに加え、OutputCache 属性は標準のASP.NET 出力キャッシュの変更オプションもサポートしています。(パラメータ、ヘッダ、エンコード、その他カスタムロジックなどによる変更)例えば、以下のサンプルは、オプションの"PageIndex" QueryStringパラメータの値によって、キャッシュされた異なるバージョンのページが保存され、自動的に受け取ったURLのクエリストリング値に応じたページが描画されます。:

また、ASP.NET データベース キャッシュ インバリデーション機能とも統合することができ、これにより自動的にURLに応じてデータベースが修正された時にキャッシュが無効化されます。(ヒント:一番いい方法はweb.configのCacheProfile セクションに設定して、OutputCache 属性でそこを指定します。)

HandleError フィルタ

[HandleError] フィルタは、ASP.NET MVC リクエストの処理中にエラーが発生した場合に、フレンドリーなエラーを表示させるコントローラもしくはアクションメソッド上で宣言的に示すものです。

これをお試しになるには、新しく"TestController"をプロジェクトに追加して以下のような例外が発生するアクションメソッドを実装します。 :

(web.configで<customErrors>セクションを構成していない場合)デフォルトでこのURLをブラウザで表示すると、デフォルトのASP.NETエラーページが表示されます。 :

[HandleError] 属性をコントローラもしくは、コントローラのアクションメソッドに追加することにより、よりフレンドリなエンドユーザ向けメッセージになるようHTMLのエラーを変更することができます。:

HandleErrorフィルタは全ての例外をとらえ(Viewテンプレートの処理中に発生するエラーを含め)、カスタムのErrorビューのリスポンスを表示します。デフォルトでは、プロジェクトで"Error"と呼ばれるViewテンプレートを解決して、リスポンスを生成しようとします。"Error" ビューは、その他のコントローラの特定のビュー(例えば:上記にあるTestControllerの\Views\Test )がある同じディレクトリ、もしくは\Views\Shared フォルダ内に置くことができます。(初めはコントローラ特定のエラービューを探し、見つからないと共有フォルダを探します。その中には、全てのコントローラで共有されるビューが含まれています。)

Visual Studioは、Preview 4でASP.NET MVC プロジェクトを新規作成した場合、現在自動的にデフォルトの"Error" ビューテンプレートを\Views\Sharedフォルダに追加します。:

[HandleError] 属性をTestControllerに追加すると、デフォルトで以下の様なHTMLのエラーページを表示します。(これはプロジェクトの中からマスターページを拾うのでエラーメッセージはサイトに統合されます。)ご存じのとおり、Errorビューテンプレートをカスタマイズして、お好きなHTMLおよびフレンドリなエラーメッセージを表示させることができます。以下は、標準搭載のものです。:

開発者のために、Visual Studio で新しいプロジェクトテンプレートとして提供されているデフォルトのErrorビューテンプレートは、アプリケーションをローカルで確認した際に追加のエラースタックのトレース情報が表示されるようになっています。:

Errorビューテンプレートからそのコードを削除するか、web.configで<customErrors> を "off"に設定すると、これを無効にすることができます。

デフォルトでは、[HandleError]フィルタはリクエストされている間に発生した全ての例外をとらえて処理します。キャッシングしたい特定の例外タイプがあれば、それを特定し、それらに対して"ExceptionType" および "View"プロパティを[HandleError] 属性で特定することで、カスタムのエラービューを指定することができます。:

上記のコードでは、SqlExceptions および NullReferenceExceptionsに対してカスタムのエラービューを表示させています。その他全ての例外はデフォルトの"Error"ビューテンプレートを使用します。

Authorize フィルタ

[Authorize] フィルタは、コントローラおよびアクションメソッド上で宣言することにより、コントロールのセキュリティアクセスが可能になります。これは、ユーザによるログインの必要性を示し、またオプションとして、アクセスするためには特定のユーザであること、または特定のセキュリティロールにあることを要求することができます。このフィルタは認証のすべてのタイプで動作し(Winodws認証およびFormsベースの認証を含む)、必要に応じて自動的に匿名ユーザをログインページへリダイレクトすることができます。

これをお試しになるには、 [Authorize] フィルタをVisual Studio がデフォルトで作成したHomeControllerに追加します。

上記の様に [Authorize] 属性を宣言している場合、ユーザは"About"アクションを要求するためにはそのサイトにログインしなければなりません。ログインしていないユーザが/Home/About URLにアクセスすると、アクセスは拒否されます。もしそのWebアプリケーションがWinodwsベース認証を使用している場合、ASP.NETは自動的にWindowsのログイン情報を使用して認証し、もしそれが成功した場合アクセスすることができます。もしWebアプリケーションがFormsベース認証を使用している場合、[Authorize] 属性が自動的にログインページへリダイレクトして認証させます。(その後アクセスすることができます。):

[Authorize] 属性はオプションで特定のユーザおよびロールのある人のみアクセスさせることができます。例えば、 "About" アクションには、自分とビル・ゲイツ氏だけしかアクセスさせたくない場合、以下の様にします。 :

通常、本当に小さなアプリケーション以外でユーザ名をハードコードすることは避けると思います。その代りパーミッションを定義するために"roles"の様な高いレベルの概念を使用し、それぞれのロールへユーザをマッピングさせます。この [Authorize] 属性は"Roles"プロパティを使用してコントローラやアクションへのアクセスを簡単に制御することができます。 :

[Authorize] 属性は、特定のユーザおよびロール管理のメカニズムをとっていません。その代り、 ASP.NET "User" オブジェクトに対して動作するため、拡張性があり全てのユーザ管理が可能です。

AccountController クラス

上記でも示しましたが、 [Authorize] 属性は全ての認証やユーザ管理システムで使用することができます。カスタムのログインUIやユーザ名・パスワード管理システムを作成または使用することが可能です。

始めやすくするために、Visual Studio のASP.NET MVC プロジェクトテンプレートには、プレビルドで"AccountController" や関連ログインビューが含まれており、フォーム認証のメンバーシップシステムが実装されるので、ログイン、ログアウト、新規ユーザの登録、パスワード変更が行えます。全てのビューテンプレートやUIは AccountControllerクラスや実装とは独立して簡単にカスタマイズすることができます。 :

Site.master テンプレートには、現在UIの右上にログイン・ログアウト機能が提供されています。フォームベース認証を使用される場合、認証されていないユーザにはログインページが表示されます。 :

そしてサイトで認証されると、Welcomeメッセージとログアウトのリンクが表示されます。 :

上記のログインのリンクをクリックすると、ユーザは以下の様なLoginのスクリーンへリダイレクトされ認証を促されます。 :

新規ユーザが登録リンクをクリックすると、アカウントを新規作成することができます。 :

エラー処理やエラー表示もビルドインされています。 :

新しいプロジェクトに追加されたAccountControllerクラスはビルドインのASP.NET Membership APIを使用して、ユーザの認証情報を保存、管理します。(MembershipシステムはプロバイダのAPIを使用して、プラグインできる全てのバックエンド保存を可能にしており、ASP.NETはActive DirectoryやSQL Serverに対してビルドインのプロバイダが含まれています。)ビルドインのMembershipシステムを使用したくない場合でも、同じAccountControllerアクションメソッドのシグネチャー、Viewテンプレート、フォーム認証チケットロジックを保存することができるので、AccountControllerクラス内でユーザアカウントのロジックを置換するだけですみます。次のASP.NET MVC Previewリリースでは、AccountControllerとユーザの認証システムをインターフェイスの背後で対話させるロジックをカプセル化しようと計画しています。そうすることで、(完全なメンバーシッププロバイダを実装することなく)独自のユーザ保存システムをプラグインしたり、それとAccountControllerの両方を単体テストすることが簡単にできるようになります。

これにより、簡単に使い始められ、プロジェクトを新規作成した時点でエンドトゥエンドのセキュリティシステムが動作する状態を提供できればと思っています。

TempDataのテスト

この最初のPreview 4の投稿での最後の改善点は、コントローラクラスへの改善で、これによりTempDataコレクションをより簡単に単体テストすることができるようになりました。このTempDataプロパティは、ユーザからの今後のリクエストを考えて、データを保存することができます。これは実行後1回のリクエストに対してのみになります。(その後削除されます。)通常MVCを使用するケースでは、ブラウザでURLを変更してクライアント側でのリダイレクトを実行したり、最初のデータを保存したいと考えている場合だと思います。

以前のASP.NET MVC Previewでは、TempDataコレクションをテストするにはオブジェクトをモックしなければなりませんでしたが、Preview 4 では、モックやセットアップは必要ありません。単体テスト内で直接コントローラのTempDataコレクションのオブジェクトを追加および検証することができます。(例えば:アクションメソッドを呼び出す前のコントローラのTempDataプロパティの紐づけ、およびアクションが戻ってきた後にTempDataを更新したアクションの検証)TempDataコレクションの実際の保存は、現在別のTempDataProvider プロパティ内でカプセル化されます。

まとめ

ASP.NET MVC Preview 4で行われた多数の新機能や改善点を、上記の投稿で一覧して頂ければ幸いです。次のASP.NET MVC Preview 4 の投稿では、AJAXの新機能とそれを利用する方法をカバーしたいとおもいます。

Hope this helps,

Scott

ScottGu's blog translated by Chica @ Wankuma 

※本翻訳に関しまして、Scottさんにはご了承頂いております。