特集
|
|
|
Ajax+ASP.NETによる郵便番号検索(テキスト通信)
さて、以下で紹介するのは、画面左のテキストボックスに郵便番号を入力したタイミングで、データベースのaddressテーブル(郵便番号情報テーブル)を検索し、対応する住所を右のテキストボックスにオート・コンプリートするASP.NETによるサンプル・アプリケーションだ。
Ajaxを利用した郵便番号による住所検索アプリケーション |
画面左のテキストボックスに郵便番号を入力すると(上画面)、リアルタイムに右のテキストボックスに対応する住所をオート・コンプリートする(下画面)。 |
本節のサンプルを動作させるには、あらかじめデータベース上に以下のようなaddressテーブルを作成しておく必要がある。
フィールド名 | データ型 | 概要 |
postnum | VARCHAR(7) | 郵便番号(主キー) |
prefecture | VARCHAR(10) | 県名 |
city | VARCHAR(50) | 市町村名 |
other | VQRCHAR(50) | 字、丁目、番地など |
addressテーブルのフィールド・レイアウト | ||
郵便番号情報については、日本郵政公社のサイトから提供されている郵便番号ダウンロードサービスを利用することで、CSV(カンマ区切りテキスト)形式のデータを入手できる(http://www.post.japanpost.jp/zipcode/) |
なお、記事冒頭の処理フロー図に本節のサンプルを当てはめると、以下のようなイメージになる。それぞれのステップが、コードのどの部分に対応するのかを意識しながら、見ていくことにしよう。
郵便番号検索サンプル・アプリケーションの仕組み |
■クライアント側スクリプトを記述する
「Asynchronous JavaScript And Xml」というその名のとおり、Ajaxの中核となるのは、クライアント・ページにおける変更イベントの検知とサーバ側との通信、そして、結果データの反映を担うJavaScriptだ。郵便番号検索サービスにアクセスするクライアント・ページのコードは、以下のようになる。
なお、本節では、サーバ側のコードとして、C#版とVB.NET版の2種類を用意している。誌面上は、VB.NET版のコードにアクセスするようにURLを指定しているが、C#版にアクセスしたい場合は、コード中の太字部分を適切なファイル名に変更してほしい。ちなみに、いずれの版を使用しても、得られる結果は変わらない。
|
|
postnum_server_vb.aspx(postnum_server_cs.aspx)から取得した住所情報を反映するWebフォーム(postnum_client.aspx) |
便宜上、拡張子は「.aspx」としているが、内容はコードをご覧いただければ分かるように、ASP.NETのコードをまったく含まない単なるHTML+JavaScriptだ。このため拡張子は、「.html」でも構わない。以上のコードで注目すべき点は、以下の3点だ。
(1)クライアント側で発生したイベントを捕捉する
クライアント側スクリプトでは、ページ上で発生したイベントをトリガーに処理を起動する「イベント駆動型」モデルとなる。対応するイベントは使用しているブラウザによって異なるが、Internet ExplorerやFirefoxで利用可能な主なイベントは以下のとおり。
イベント | 発生するタイミング |
onblur | 要素からフォーカスが外れたとき |
onchange | 要素の内容が変更されたとき |
onclick | 要素をクリックしたとき |
ondblclick | 要素をダブルクリックしたとき |
onfocus | 要素にフォーカスが当たったとき |
onkeydown | キーを押したとき |
onkeyup | キーを離したとき |
onload | ページがロードされたとき |
onmousedown | マウスボタンを押したとき |
onmousemove | マウスが移動したとき |
onmouseout | マウスが要素から外れたとき |
onmouseover | マウスが要素に乗ったとき |
onmouseup | マウスボタンを離したとき |
onreset | リセットされたとき |
onselect | テキストが選択されたとき |
onsubmit | フォームがサブミットされたとき |
onunload | ページがアンロードされたとき |
クライアント側スクリプトで利用可能な主なイベント |
ここでは、テキストボックス「postnum」が変更されたタイミング(onchangeイベント発生時)で、JavaScriptのsearch関数を呼び出し、サーバとの通信処理を開始している。
(2)サーバとの通信を行うのはXMLHttpRequestオブジェクトの役割
サーバ側(本稿ではASP.NET)との非同期通信を管理するのは、XMLHttpRequestオブジェクトの役割だ。XMLHttpRequestオブジェクトは、多くのブラウザで古くから実装されているオブジェクトであるが、反面、ブラウザ独自の実装も多いので注意が必要だ。
その最たるものがオブジェクトの生成方法である。ここでは、例外処理を利用して、まずtryブロックでXMLHTTPオブジェクト(IE用)の生成を試み、それに失敗した場合はcatchブロックでXMLHttpRequestオブジェクト(Firefox用)を生成するという方法を採っている。これによって、ブラウザに合わせたオブジェクトを生成できるというわけだ。
XMLHttpRequestオブジェクトで利用可能なプロパティ/メソッドは以下のとおり(なお、以降は、XMLHTTPオブジェクトも含め「XMLHttpRequest」と表記する)。
分類 | メンバ名 | 概要 | |||||||||||
プロパティ | onreadystatechange[R/W] | XMLHttpRequestオブジェクトの状態が変化したタイミングで呼び出されるイベント・ハンドラ | |||||||||||
readyState[R] | HTTP通信の状態を取得
|
||||||||||||
responseBody[R] | レスポンスとして返される複数フォームの1つを取得 | ||||||||||||
responseText[R] | レスポンスをプレーン・テキストとして取得 | ||||||||||||
responseXML[R] | レスポンスをXMLDocumentオブジェクトとして取得 | ||||||||||||
status[R] | HTTPステータスコードを取得。200:OK、404:Not Foundなど | ||||||||||||
statusText[R] | HTTPステータスの詳細メッセージを取得 | ||||||||||||
メソッド | abort() | 現在行っているHTTP要求を中断 | |||||||||||
getAllResponseHeaders() | 受信した全HTTP応答ヘッダを取得(sendメソッドが成功した後にのみ有効) | ||||||||||||
getResponseHeader(header) | 指定されたHTTP応答ヘッダを取得(sendメソッドが成功した後にのみ有効) | ||||||||||||
open(method ,url [,async [,usr [,passwd]]]) | 指定されたHTTPメソッド(GET|POST|PUT|PROPFIND)で指定URLにリクエストをオープン(asyncは非同期モードかどうか、usr、passwdは認証が必要な場合にのみ指定) | ||||||||||||
send(body) | HTTP要求を送信(POSTメソッドで送信した場合には、bodyに要求ボディを指定可能) | ||||||||||||
setRequestHeader(header,value) | HTTP要求時にヘッダを追加 | ||||||||||||
XMLHttpRequestオブジェクトで利用可能なプロパティ/メソッド | |||||||||||||
プロパティ名に併記した[R/W][R]は、それぞれ「読み書き可能」「読み取り専用」を表す。 |
サーバ側から返された戻り値を捕捉し、クライアント・ページに反映させるのは、onreadystatechangeイベント・ハンドラの役割だ。onreadystatechangeイベントは、XMLHttpRequestオブジェクトの状態(ステータス)が変更されたタイミングで発生するイベントである。これに設定したJavaScriptの関数(コールバック関数)は、そのタイミングで呼び出される(コールバックされる)ことになる。
ここでは、XMLHttpRequestオブジェクトの全データが取得済み(readyStateプロパティがCOMPLETED)であり、かつ、HTTPステータスコード(statusプロパティ)が「200」(OK)である場合に、サーバ側から送られてきたデータを取得し、それを右側のテキストボックス「address」の値としてセットしているというわけだ。
サーバ側からの戻り値を取得するメソッドは、XMLHttpRequestオブジェクトにいくつか用意されているが、プレーン・テキストとして取得するにはresponseTextプロパティを使えばよい。
XMLHttpRequestオブジェクトは、もともとはXMLデータを授受するために用意されたオブジェクトであるが、なにも利用できるのはXMLデータばかりではない。本節のサンプルのようにプレーン・テキスト(HTMLを含んでも可)を扱うことも可能だ。本節サンプルのような住所情報ならば、プレーン・テキストとしてデータを取得した方が、クライアント側でDOM(Document Object Mode)による処理を行う必要もなく、コードがシンプルに記述できるはずだ。
なお、XMLHttpRequestオブジェクトで扱える文字コードは「UTF-8」に限定されるので、注意すること。ほかの文字コードを利用している場合には、マルチバイト文字が文字化けする原因となる。ASP.NETではデフォルトの応答文字コードはUTF-8に設定されているので、特に構成を変更しない限りは問題ないはずだ。
[参考]ASP.NETの応答文字コード | ||||||||||||||||||
ASP.NETの応答文字コードの設定個所は、以下の3カ所である。
通常は、machine.configにデフォルトで設定されている文字コード(UTF-8)がデフォルト値になっているはずだ。もしもmachine.config上に明示的に値が設定されていない場合、システム・デフォルトの文字コードが使用される。 Ajaxアプリケーションで文字化けが発生した場合にはこれらを確認し、ASP.NETから正しくUTF-8で応答が返されているかどうかを確認していただきたい。 |
(3)サーバ側にデータを送信するのはsendメソッド
コールバック関数の定義が終わったら、後はサーバに対してHTTPリクエストを発行するだけだ。リクエストを初期化するのは、XMLHttpRequestオブジェクトのopenメソッドの役割だ(リクエスト時に特別な要求ヘッダを設定したい場合には、setRequestHeaderメソッドを利用することも可能)。
openメソッドには、第1パラメータからHTTPメソッド、URL、非同期モード指定、ユーザー名、パスワードの順でパラメータを指定できる(第3パラメータ以降は任意)。ただし、XMLHttpRequestオブジェクトでは、セキュリティ上の理由から、URLにページと異なるドメインをセットすることはできない。使用しているブラウザによっては、同一ドメインでもドメインを明示するだけで正しく処理できないものもあるので注意が必要だ。URLには必ずパスのみ(「http://」は不要)を指定するようにすること。
リクエストの準備ができたら、sendメソッドでリクエストを送信する。sendメソッドのパラメータには、openメソッドの第1パラメータに「POST」を指定した場合にのみ、要求本体を指定することができる。繰り返しになるが、このHTTP要求の結果は、onreadystatechangeイベント・ハンドラで処理することができる。
■サーバ側のコードを記述する
クライアント・ページの挙動を理解したところで、次にサーバ側のコードを見てみよう。今回の場合には、サーバ側のコードは非常にシンプルだ。
|
|
郵便番号をキーに県名+市町村名を取得するWebフォーム(C#版:postnum_server_cs.aspx) |
|
|
郵便番号をキーに県名+市町村名を取得するWebフォーム(VB.NET版:postnum_server_vb.aspx) |
サーバ側で行っている内容は、なんということはない。クライアント・ページから受け取ったクエリ情報「postnum」をキーにaddressテーブルを検索し、取得した「県名+市町村名」をHttpResponseオブジェクトのWriteメソッドで出力するだけだ。
本稿は、サーバ側をASP.NETで実装しているが、もちろん、JSP(JavaServer Pages)&サーブレットやPHP(PHP:Hypertext Preprocessor)など、ほかの技術を利用しても、ほとんど同じ要領で記述できる。
なお、ここではクライアント側への応答をテキスト形式で出力しているので、@PageディレクティブのContentType属性は「text/plain」と明示しておこう。
INDEX | ||
[特集]枯れた新しいUI革命「Ajax」をASP.NETで活用する | ||
1.Ajax技術の基本的な仕組みとアプリケーション例 | ||
2.Ajax+ASP.NETによる郵便番号検索(テキスト通信) | ||
3.Ajax+ASP.NETによる郵便番号あいまい検索(XML通信) | ||
4.JavaScriptライブラリ活用で高度なAjax連携 | ||
- 第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用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|