.NET TIPS

[ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(クライアントサイド編)[2.0のみ、C#、VB]

山田 祥寛
2007/06/28

 本稿は「TIPS:[ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(サーバサイド編)」の続きである。サーバサイド編で作成したServiceBridge.asmxを、本稿ではクライアントサイド・スクリプト(JavaScript側)から呼び出す方法について紹介する。

 サーバサイド編でも示したが、サンプル・アプリケーションの実行結果は次の画面のようになる。

郵便番号「1840002」を入力
ASP.NET AJAXを利用した郵便番号による住所検索アプリケーション
画面左のテキストボックスに郵便番号を入力すると(上画面)、対応する住所をリアルタイムにオートコンプリートして右のテキストボックスに表示していく(下画面)。

1. 新規のWebフォームを作成する

 新規のWebフォーム(ServiceBridge.aspx)を作成したら、フォーム・デザイナから以下の画面の要領でサーバ・コントロールを配置する。また、それぞれのコントロールに対しては、表の内容でプロパティ値を設定しておこう。

Webフォーム(ServiceBridge.aspx)のレイアウト
各コントロールのプロパティ内容は以下のとおり(およびはHTMLコントロール)。
コントロール(ID) プロパティ 設定値
ScriptManager(manager) Services ServiceBridge.asmx(設定方法は後述)
Input[Text](postnum) Size 10
onchange* return postnum_onchange()
Input[Text](address) Size 50
* ただし、onchangeプロパティはプロパティ・ウィンドウからは設定できない。設定を行うには、コードエディタ上部の選択ボックスから「postnum(コントロールのID値)」「onchange」と選択する必要がある。

 ScriptManagerコントロールは、その名のとおり、ASP.NET AJAXの動作に必要なクライアントサイド・スクリプトの出力/生成などを担当するためのコントロールだ。ASP.NET AJAXの機能を利用する場合には、必ず「ページの先頭に1つだけ配置する」必要がある。

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

[ServiceReference コレクション エディタ]ダイアログ
ScriptManagerコントロールのScriptManager.Servicesプロパティにある[...]ボタンをクリックして開く。アクセスするXML Webサービス・クラスをここで登録しておく。

 上の画面のような[ServiceReference コレクション エディタ]ダイアログが表示されるので、ダイアログ左下の[追加]ボタンをクリックし、右のプロパティ・グリッドからPathプロパティに「ServiceBridge.asmx」へのパスを指定すればよい。

 この設定によって、ScriptManagerコントロールは、ページ生成時に登録された.asmxファイル(ここでは「ServiceBridge.asmx」)のプロキシ・クラスを生成する。プロキシ・クラスとは、その名のとおり、サービス・メソッドへのプロキシ(=代理)の役回りを担うものだ。プロキシ・クラスを介することで、クライアントサイド・スクリプトではあたかもローカルのライブラリにアクセスするかのようにサーバ側のサービス・メソッドにアクセスできるというわけだ。

 プロキシ・クラスを介してWebサービスを利用する際の動作の流れ(=サービス・ブリッジ機能)をまとめたのが次の図である。

サービス・ブリッジ機能の仕組み

[参考]

ASP.NET AJAXによって生成されるプロキシ・クラスの実コードを確認したい場合には、サービス・クラスの末尾に「/js」を付与して呼び出せばよい。例えば、本サンプルの例であれば、以下のURLでプロキシ・クラスのコードを参照できる。

http://localhost:<ポート番号>/ServiceBridge.asmx/js

 なお参考までに、ここまでにVisual Studio 2005で自動生成されたコードを引用しておく。<%--〜--%>は筆者によるコメントである。

<%--ASP.NET AJAXを使用する場合には先頭にScriptManagerの配置は必須--%>
<asp:ScriptManager ID="manager" runat="server">
  <%--.asmxファイルをサービスとして登録--%>
  <Services>
    <asp:ServiceReference Path="ServiceBridge.asmx" />
  </Services>
</asp:ScriptManager>
郵便番号検索<br /><br />
郵便番号:
<input id="postnum" size="10" type="text"
  language="javascript" onchange="return postnum_onchange()" />
<input id="address" size="50" type="text" />
ServiceBridge.aspxのソース・コード(抜粋)
一連のレイアウト編集を行った後、Visual Studio 2005によって自動生成されたコードを引用したもの。

2. サービス呼び出しのコードを記述する

 あとは、手順1で定義したプロキシ・クラスを介して、サービス・メソッドを呼び出すJavaScriptのコードを記述するだけだ。具体的なコードは以下のとおり。

<script language="javascript" type="text/javascript">
<!--
function postnum_onchange() {
  ServiceBridge.GetAddressByPostnum(
    $get('postnum').value,
    function(result,cx,name) { $get('address').value = result; },
    function(ext,cx,name) { $get('address').value = ext.get_message(); }
  );
}
// -->
</script>
プロキシ・クラス経由でサービス・メソッドにアクセスするコード(ServiceBridge.aspx)

 postnum_onchange関数は、テキストボックスpostnumが変更されたタイミングで呼び出されるイベント・ハンドラだ。イベント・ハンドラ内では、プロキシ・クラス経由でServiceBridge.asmxで定義されたGetAddressByPostnumメソッドを呼び出している。

 プロキシ・クラス呼び出しの一般的な構文は以下のとおりだ。

クラス名.メソッド名(
  [パラメータ, ……]
  ,処理成功時に呼び出されるコールバック関数
  [,サービス側で例外が発生した場合に呼び出されるコールバック関数
    [,任意のコンテキスト値]
  ]
)
プロキシ・クラスの一般的な呼び出し構文
ただし、クラス名は厳密には「完全修飾名」。従って、名前空間に属するクラスの場合は、名前空間まで含めた名前で指定する必要がある。

 コールバック関数とは、サーバ側から結果(あるいは例外)が返されたタイミングで呼び出される関数のことだ。以降では、それぞれ「成功コールバック」「例外コールバック」と呼ぶものとする。以下、これらのコールバック関数について処理内容を解説する。

[参考]

ちなみに、本サンプルではコールバック関数を「匿名関数」(=名前を持たない関数)として記述しているが、もちろん通常の名前付き関数として定義することも可能だ。従って、以下の2つの記述は意味的に等価である。

function postnum_onchange() {
  ServiceBridge.GetAddressByPostnum(
    $get('postnum').value,
    function(result,cx,name) { $get('address').value = result; },
    function(ext,cx,name) { $get('address').value = ext.get_message(); }
  );
}
コールバック関数として匿名関数を指定した場合

↑↓

function postnum_onchange() {
  ServiceBridge.GetAddressByPostnum(
    $get('postnum').value,
    OnSuccess,
    OnFailure
  );
}

function OnSuccess(result,cx,name) {
  $get('address').value = result;
}
function OnFailure(ext,cx,name) {
  $get('address').value = ext.get_message();
}
コールバック関数として通常の関数を指定した場合

コールバック関数を複数の呼び出し元から共通して利用する場合には、後者の記法(通常の関数)を利用した方が重複して処理を記述する必要がなくなる。一方、本サンプルのように、呼び出し元とコールバック関数とが1対1の関係にある場合には、匿名関数を利用することでより対応関係も分かりやすく、一連の処理を1カ所にまとめて記述できるというメリットがある。

 プロキシ・クラス呼び出し時に指定する「コンテキスト値」とは、コールバック関数の側で呼び出し元の識別などを行うためのキー値だ。本サンプルでは呼び出し元とコールバック関数が1対1の関係にあるので、コンテキスト値は指定していないが、もしも両者の関係が1対多の関係にある場合は、コンテキスト値を利用することで、呼び出し元に応じて処理を分岐するようなコーディングも可能だ。

(1)成功コールバック

 成功コールバックでは、パラメータとして「サーバ・メソッドからの処理結果」「コンテキスト値」「呼び出し元のメソッド名」を受け取り、その内容に基づいて、ページの更新処理を実行する。本サンプルでは、サービス・メソッドから受け取った住所情報をテキストボックスaddressにセットしている(コンテキスト値、メソッド名は使用していない)。

 ちなみに、$get関数はASP.NET AJAXで提供されるユーティリティ関数の1つで、document.getElementByIdメソッドのエイリアス(=別名)だ。従って、以下の2文は意味的に等価である。

document.getElementById('address').value
  ||
$get('address').value

 getElementByIdメソッドはクライアントサイド・スクリプトの中でも特によく使うメソッドの1つであるので、$get関数はぜひとも覚えておきたいところだ。$get関数を利用することで、getElementByIdメソッドの繰り返しを防いでコードを簡素化できる。

(2)例外コールバック

 例外コールバックでは、パラメータとして「サーバ・メソッドで発生した例外情報(Sys.Net.WebServiceErrorクラス)」「コンテキスト値」「呼び出し元のメソッド名」を受け取り、例外情報をエンド・ユーザーに通知するなどの例外発生時の処理を定義する。

 Sys.Net.WebServiceErrorクラスで利用可能なプロパティは、以下のとおり。

プロパティ 概要
exceptionType 例外の種類
message 例外メッセージ
statusCode HTTPレスポンスのステータス・コード
stackTrace サーバから返されたスタックトレース
timedOut タイムアウトによってサービスが失敗したのか
Sys.Net.WebServiceErrorクラスで利用可能な主なプロパティ

 なお、プロパティ値にアクセスするには「オブジェクト名.get_プロパティ名()」の形式で記述する必要がある。本サンプルの例では、サービス・メソッドの側で例外が発生した場合に、そのメッセージ情報をテキストボックスaddressにセットしている。

 以上を理解したら、さっそく作成したサンプル・プログラムを実行してみよう。冒頭の画面のように、左のテキストボックスに郵便番号を入力すると、それに対応する住所情報が右のテキストボックスに表示されることが確認できれば成功だ。

 なお、本稿ではプロキシ・クラスの基本的なメソッド呼び出しについてのみ紹介したが、プロキシ・クラスでは標準的なプロパティとして以下のようなものが利用可能であるので、最後にまとめておく。自分でアプリケーションを開発する際の参考にしていただきたい。

プロパティ 概要
defaultFailedCallback デフォルトで適用される例外コールバック関数
defaultSucceededCallback デフォルトで適用される成功コールバック関数
defaultUserContext デフォルトのコンテキスト値
path XML Webサービス・メソッドのパス
timeout デフォルトのタイムアウト値
プロキシ・クラスで利用可能な共通プロパティ

 defaultXxxxxプロパティは、プロキシ・クラスにデフォルトで適用されるコールバック関数やコンテキスト値などを適用するものだ。ページ内の複数個所から同一のプロキシ・クラスを利用する場合で、かつ、共通のコールバック関数やコンテキスト値を使用する場合には、個々のメソッド呼び出し時に指定するのではなく、あらかじめdefaultXxxxxxプロパティで指定しておくことで、重複した記述を回避することができる。

 なおプロパティを参照/設定するには、先述したように、

参照:
クラス名.get_プロパティ名()
設定:
クラス名.set_プロパティ名(設定値)

とする必要があるので、注意すること。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:Webフォーム 処理対象:ASP.NET AJAX
関連TIPS:[ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(サーバサイド編)

この記事と関連性の高い別の.NET TIPS
[ASP.NET]ページを再読み込みせずにサーバと通信を行うには?
[ASP.NET AJAX]Webサービス・ブリッジ機能により構造化データを受け渡しするには?(基本編)
[ASP.NET AJAX]クライアントサイド・スクリプトからASP.NETの認証機能を利用するには?
[ASP.NET]Ajax.NETでAjaxプログラミングを効率化するには?
[ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(サーバサイド編)
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間