さる11月6日,ASP.NET AJAX β2版がリリースされました。これに伴い,本連載でも以降の回ではβ2環境を前提に紹介していく予定です。β2での変更点はいくつかありますが,ここでは一点だけ。従来のβ1版ですでにアプリケーションを構築している方は必ずアプリケーション構成ファイル「Web.config」*1をβ2版のものに置き換える必要がある,という点に注意してください。さもないと,ASP.NET AJAXを利用したページの実行時に「'Sys'が定義されていません」というJavaScriptの実行時エラーが発生します。

 さて,それでは前置きはこのくらいにして,本題に行ってみましょう。

 前回は書籍検索アプリケーションのサーバーサイド機能を実装する方法について紹介しました。今回は引き続き,サーバーサイドで用意された機能(メソッド)をクライアントサイドから呼び出し,ブラウザ上に結果を表示してみることにしましょう。

クライアントページのレイアウトを定義する

 それではさっそく,具体的な手順を見ていきます。ソリューションエクスプローラから新規のBookSearch.aspxを作成し,図1のようにコントロールの配置とテキストの入力を行ってください。ScriptManagerコントロールはツールボックスの[AJAX Extensions]タブに,その他のコントロールは[HTML]タブに,それぞれ含まれています*2

図1:BookSearch.aspxのフォーム・レイアウト

 また,それぞれのコントロールに対して,表1の要領でプロパティを設定しておきます。

表1:BookSearch.aspxのプロパティ設定
コントロールプロパティ設定値
ScriptManager(ID)manager
Services下記詳細
Input(Text)(Id)txtIsbn
Input(Button)(Id)btnSearch
Value検索
Div(Id)ltrResult
Style△(ブランク)

 ScriptManagerコントロールは,その名の通り,ページ上のクライアントサイドスクリプトを管理するためのコントロールで,ASP.NET AJAXの動作に必要なライブラリの出力/生成などの役割を担います。ASP.NET AJAXを利用する場合,ScriptManagerコントロールは必ずページ先頭に一つだけ配置する必要があります*3

 クライアントサイドスクリプトからサーバーメソッド(XML Webサービスメソッド)にアクセスする場合には,ScriptManagerコントロールに対してアクセス先のサービスを登録しておく必要があります。サービスを登録するには,プロパティウィンドウのServicesプロパティ右端から[...]ボタンをクリックします。

図2:[ServiceReferenceコレクションエディタ]ダイアログ(クリックすると拡大表示します)

 [ServiceReferenceコレクションエディタ]ダイアログが開きますので,左下の[追加]ボタンをクリックし,図2の要領で前回作成したBookSearch.asmxを登録しておきます。

 これでサーバーサイド機能にアクセスするための準備が整いました。ここで参考までにVisual Studio 2005で自動生成されたコードを引用しておきます(リスト1)。

リスト1:BookSearch.aspx

<form id="form1" runat="server">
<div>
  <asp:ScriptManager ID="manager" runat="server">
    <Services>
      <asp:ServiceReference Path="~/BookSearch.asmx" />
    </Services>
  </asp:ScriptManager> *4
  ISBNコード:<input id="txtIsbn" type="text" />
  <input id="btnSearch" type="button" value="検索" /><br />
  <div id="ltrResult"></div>
</div>
</form>

クライアントサイドスクリプトを実装する

 次に,[検索]ボタンがクリックされたタイミングで実行されるクライアントサイドのコードを記述します。フォームデザイナ上に配置したボタンをダブルクリックすると,コードエディタが開きます。コードエディタには,デフォルトで最低限のコードが自動生成されています。リスト2のように,コードを入力してみましょう(追記部分は太字)。

リスト2:BookSearch.aspx

<script language="javascript" type="text/javascript">
<!--
function btnSearch_onclick() {
  BookSearch.GetTitleByIsbn(
       $get('txtIsbn').value, OnComplete);
}

function OnComplete(result){ $get('ltrResult').innerHTML=result; }

// --> </script>

 [検索]ボタンをクリックしたタイミングで呼び出されるbtnSearch_onclick関数に注目してみましょう。BookSearchは,ASP.NET AJAXによって動的に生成されたプロキシクラスです。プロキシクラス(Proxy Class)とは,その名の通り,同名のXML Webサービスクラスへのアクセスを代理(Proxy)で行うクラスです*5。プロキシクラスを介することで,あたかもローカルのライブラリにアクセスするのと同じ要領で,サーバーサイド機能を呼び出すことができるというわけです。プロキシクラスの一般的な構文は,以下の通りです。

クラス名.メソッド名([引数,...,] コールバック関数) *6

 コールバック関数とは,サーバーサイドから応答を得たタイミングで,その結果に基づいて処理を行うための関数です。コールバック関数(ここではOnComplete関数)は,引数としてサーバーメソッドからの戻り値を受け取ります。

 コールバック関数の中で呼び出されている「$get(...)」はページ内のHTML要素にアクセスするためのショートカットとなるもので,以下の2文は同意です*7

document.getElementsById('ltrResult').innerHTML
  ⇔ $get('ltrResult').innerHTML

 つまりここでは,テキストボックス(txtIsbn)で入力されたISBNコードをキーに,サーバーメソッドGetTitleByIsbnを呼び出し,その結果(対応する書名)を

タグにセットしているというわけです。

 なお,ここではよりわかりやすくするという意味で,コールバック関数を呼び出し元とは分離して記述していますが,匿名関数で一つにまとめてしまっても構いません。呼び出し元とコールバック関数とが一対一の関係にあるならば,匿名関数を用いた方がコードをシンプルに記述できます。以下に書き換えたコードを示します。

function btnSearch_onclick() {
  BookSearch.GetTitleByIsbn($('txtIsbn').value,
    function(result){$get('ltrResult').innerHTML=result;});
}

[コラム]
メソッド例外時の処理を記述する

 ちなみに,サーバーメソッドで例外が発生した場合,その情報をプロキシクラス(クライアント)側で受け取ることも可能です。その場合,本文のコードにリストAの内容を追記してください。

リストA:例外処理用のコード

function btnSearch_onclick() {
  BookSearch.GetTitleByIsbn(
    $get('txtIsbn').value, OnComplete, OnFailure);
}
  ...中略...
function OnFailure(ex){
  window.alert("エラー発生" + ex.get_message())
}

 このような記述によって,サーバーメソッドで処理されない例外が返された場合には,その情報をSys.Net.WebServiceErrorオブジェクトとして受け取ることが可能になります。

 WebServiceErrorクラスの主なメソッドは,以下の通りです。

メソッド名概要
get_exceptionType例外の種類
get_stackTraceスタックトレース
get_messageエラー・メッセージ
get_statusCodeエラーステータス
get_timeOutタイムアウト時間

  例外を処理するのは,コールバック関数OnFailureの役割で,サーバーメソッド呼び出し時に,成功時コールバック関数(ここではOnComplete)の後方に指定することができます。

 いかがですか。こうして説明してみると,やや回りくどく感じるかもしれませんが,別稿「基本的なAjaxアプリケーションを作成してみよう(前編)」のコードと比べてみると,一目瞭然。XMLHttpRequestオブジェクトによる通信手続きが一切必要なくなったことで,コードがぐっとシンプルになっていることがおわかりいただけるはずです。

 次回は,引き続きASP.NET AJAXを用いた構造データの扱いについて紹介します。

 本連載はASP.NET AJAX β2リリース(2006年11月06日時点)の情報を基に執筆しています。今後のRelease Candidate版,正式版などでは仕様が変更される可能性がありますのでご注意ください。