ASP.NET MVCにおけるAJAX対応
ASP.NET AJAX(Extensions/Control Toolkit)とASP.NET MVCの相性はポストバックの非利用という点からも推測できるかと思いますが、相性はよくありません。しかし、ASP.NET MVCではMVC専用のAJAXクラスが用意されています。
メソッド | 概要 |
ActionLink | Ajaxを利用した”文字列”を返すハイパーリンクを生成 |
BeginForm | Ajaxを利用したViewや文字列を返すフォームを生成 |
BeginRouteForm | Ajaxを利用したViewや文字列を返す異なるルートのフォームを生成 |
RouteLink | Ajaxを利用した”文字列”を返す異なるルートへのハイパーリンクを生成 |
HtmlHelperクラスに比べて、AjaxHelperクラスは利用できるメソッドが少なく、大別すると2種類しかありません。
ActionLinkメソッドは文字列を、BeginForm/BeginRouteFormメソッドはViewや文字列を部分更新します。実開発ではパーシャルレンダリングの時のみの利用とし、それ以外の例えばアニメーションなどを実装したい場合はjQueryなどを利用して実装します。
また、BeginForm/BeginRouteFormメソッドはHtml.BeginForm同様にusingステートメントを使い、通常の構文同様{}内に非同期通信をする要素の記述をします。
なお、AJAXリクエストを判別するためにRequest.IsAjaxRequest拡張メソッドがあります。このIsAjaxRequestメソッドはASP.NET AJAX(Microsoft AJAX Library)のリクエストは勿論、jQuery、Prototype.js等のJavaScriptライブラリのAJAXリクエストにも対応しています。このメソッドのメリットとして、AjaxHelperクラスによるAJAXリクエストを判定し、ページの中でAJAXを利用したユーザーコントロールの部分更新が可能になります。実際の活用サンプルは次のようになります。
BeginFormメソッドを利用したサンプル
実行した画面は図5~6のようになります。ユーザーコントロールは、テーブルタグに画像と文字を埋め込んだだけのあまり意味の無いサンプルなので、割愛させていただきます。詳しくはサンプルを参照ください。
コントローラ側の処理はこちら。
public ActionResult AJAXRequest() { //非同期通信の判定 if (Request.IsAjaxRequest()) { // AJAXリクエストの時はPartialPage.ascxを返す return PartialView("PartialPage"); } //同期通信の場合はIndex.aspxを返す return View("AJAXIndex"); }
上記コードではIsAjaxRequestメソッドを使い、非同期通信のリクエストがあった時のみ、部分ページとしてユーザーコントロールを表示させます。もし通常のリクエストであればIndex.aspxページを返します。
フォーム側の処理はこちらです。BeginFormメソッドの1番基本的な使い方は第一パラメタにActionメソッド名、第二パラメタにAjaxOptionsクラスを設定します。AjaxOptionsクラスは、ASP.NET MVCでAJAXを実行する場合のオプションを設定するクラスです。
オーソドックスな利用方法として、AJAXの動作の対象要素IDをUpdateTargetIdで指定します。
なお、usingブロック内で通信が発生した場合に非同期通信が発生します。
<%--Ajax.BeginForm(Actionメソッド名 , new AjaxOptions() { UpdateTargetId=Ajax動作の対象要素ID}) --%> <% using (Ajax.BeginForm("AJAXRequest", new AjaxOptions() { UpdateTargetId = "divView" })) { %> <%-- ボタンクリック時にAJAXRequestメソッドを経由する --%> <input type="submit" value="部分更新" /> <% } %> <div id="divView"> </div>
上記の部分では、BeginFormメソッドで、AJAXRequestアクションメソッドと、AJAXによる通信結果の動作の対象要素IDをdivViewに設定しています。
ActionLinkメソッドと、IsAjaxRequestメソッドを利用したサンプル
実行した画面は図7~8のようになります。
コントローラ側の処理はこちら。
[OutputCache(Duration = 5, VaryByParam = "none")] public string WhatTimeIsIt() { return DateTime.Now.ToString(); }
上記コードでは、OutputCache属性でDurationプロパティを5に、VaryByParamプロパティを"none"に設定しています。戻り値は、現在の時刻を返しています。
フォーム側の処理はこちらです。Ajax.ActionLinkメソッドはHtml.ActionLink同様にハイパーリンクが表示されます。違いはリンクをクリックした時の通信が同期か、非同期かの違いです。Ajax.ActionLinkメソッドの1番基本的な使い方は第一パラメタにリンクテキストを、第二パラメタにActionメソッド名、第三パラメタにAjaxOptionsクラスを設定します。
<%-- Ajax.ActionLink(リンクテキスト,Actionメソッド名 , AjaxOptions { UpdateTargetId=Ajax動作の対象要素ID}) --%> <%= Ajax.ActionLink("現在時刻表示", "WhatTimeIsIt", new AjaxOptions { UpdateTargetId = "TimeDate" })%> <div>時間:<span id="TimeDate"></span></div>
上記の部分では、ActionLinkメソッドで、"現在時刻表示"というハイパーリンクをクリックしたときにWhatTimeアクションメソッドにルーティングされるように設定し、AJAXによる通信結果の動作の対象要素IDをTimeDateに設定しています。
以上がサーバーサイドのAJAX専用クラスを利用したサンプルの紹介でした。何度も記述していますが、クライアントスクリプトは、Microsoft AJAX LibraryやjQueryの標準サポートが行われています。部分更新以外のAJAX機能を利用する際はこちらを利用してください。