.NET TIPS

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

山田 祥寛
2007/06/21

 ASP.NET AJAXというと、UpdatePanelコントロールやTimerコントロールのような、いわゆるAJAX Extensionsコントロール(ASP.NET AJAXが提供するサーバ・コントロール)に目が向きがちであるが、ASP.NET AJAXは単なるコントロール・ライブラリではない。「DBプログラミング 7つのヒント − 同時実行制御からASP.NET AJAXまで −」で紹介しているように、ASP.NET AJAXはサーバ/クライアント双方にまたがって、AJAX開発をサポートする総合的なフレームワークだ。

 ここでは、ASP.NET AJAXが提供する重要な機能の1つである「ブリッジ機能」を利用する方法を紹介する。ブリッジ機能とは、ASP.NET 2.0のメンバシップ・フレームワークやXML Webサービスをクライアントサイド・スクリプトからアクセス可能にするための仲介役(=ブリッジ)となるものだ。ブリッジ機能を利用することで、XMLHttpRequestオブジェクトなどの原始的な通信の手続きを意識することなく、クライアントサイドからサーバ上で定義されたメソッド(やサービス)を呼び出すことができる。

 なお、厳密にはブリッジ機能は、メンバシップ・フレームワークなどのASP.NETが標準で提供するサービスを呼び出すための「アプリケーション・ブリッジ」と、開発者が自作したXML Webサービス・クラスを呼び出すための「Webサービス・ブリッジ」とに分類できるが、本稿ではWebサービス・ブリッジ機能について紹介する。アプリケーション・ブリッジ機能については、後日、「TIPS:[ASP.NET AJAX]ASP.NET AJAX経由でユーザー認証を行うには?」および「TIPS:[ASP.NET AJAX]ASP.NET AJAXからユーザー・プロファイル機能を利用するには?」で紹介する予定だ。

 それではさっそく、ブリッジ機能を利用したサンプルを紹介していくことにしよう。

 ここで紹介するサンプル・アプリケーションは、「枯れた新しいUI革命「Ajax」をASP.NETで活用する」で紹介した郵便番号検索アプリケーションを、ASP.NET AJAXを使って書き直したものだ。標準的なASP.NET+JavaScriptで記述した場合と比べ、こちらのコードがいかに簡素化されるかを見てみるのもよいだろう。

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

 それではさっそく、具体的な手順を追っていくことにしよう。なお、本サンプルを動作させるには、「DBプログラミング 7つのヒント」の内容に従って、ASP.NET AJAXをインストールしておく必要がある。

1. 住所検索のためのデータベースを用意する

 本稿のサンプルを動作させるには、あらかじめデータベース上に以下のようなaddressテーブルを作成しておく必要がある。

フィールド名 データ型 概要
postnum VARCHAR(7) 郵便番号(主キー)
prefecture VARCHAR(10) 県名
city VARCHAR(50) 市町村名
other VARCHAR(50) 字、丁目、番地など
addressテーブルのフィールド・レイアウト

 ちなみに、郵便番号情報については、日本郵政公社のサイトから提供されている「郵便番号ダウンロード・サービス」を利用することで、CSV(カンマ区切りテキスト)形式のデータを入手できる。本データを利用してaddressテーブルに必要なデータをセットアップしておこう。

2. 新規のXML Webサービス・クラスを定義する

 ASP.NET AJAXにおいてサーバサイドの機能を提供するのは、.asmxファイル(=XML Webサービス・クラス)の役割だ。

 ここでは、クライアント・ページから送信された郵便番号(postnumパラメータ)をキーにaddressテーブルを検索し、合致した住所情報を文字列として返すXML Webサービス・クラス(ServiceBridge.asmx)を定義してみよう。ServiceBridge.asmxの具体的なコードは、以下のとおり。

<%@ WebService Language="C#" Class="ServiceBridge" %>

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.Common;
using System.Web;
using System.Web.Script.Services;
using System.Web.Services;
using System.Web.Services.Protocols;

[WebService(Namespace="http://tempuri.org/")]
[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
[ScriptService()]
public class ServiceBridge : System.Web.Services.WebService {

  [WebMethod()]
  public String GetAddressByPostnum(String postnum) {

    String result = null;

    ConnectionStringSettings setting =
      ConfigurationManager.ConnectionStrings["MyDB"];
    DbProviderFactory factory =
      DbProviderFactories.GetFactory(setting.ProviderName);

    using (DbConnection db = factory.CreateConnection()) {
      db.ConnectionString = setting.ConnectionString;
      DbCommand comm = factory.CreateCommand();

      // postnumパラメータをキーに住所情報を検索
      comm.CommandText =
        "SELECT prefecture, city, other FROM Address WHERE postnum=@postnum";
      comm.Connection = db;
      DbParameter param = factory.CreateParameter();
      param.ParameterName = "@postnum";
      param.Value = postnum;
      comm.Parameters.Add(param);
      db.Open();
      DbDataReader reader = comm.ExecuteReader();

      // 取得した県、市、そのほかの情報を連結し、戻り値を生成
      if (reader.Read()) {
        result = reader["prefecture"].ToString() +
          reader["city"].ToString() + reader["other"].ToString();
      } else {
        // 合致するレコードが存在しない場合は例外をスロー
        throw new Exception("該当するデータが存在しません。");
      }
    }
    return result;
  }
}
<%@ WebService Language="VB" Class="ServiceBridge" %>

Imports System.Collections.Generic
Imports System.Data
Imports System.Data.Common
Imports System.Web
Imports System.Web.Script.Services
Imports System.Web.Services
Imports System.Web.Services.Protocols

<WebService(Namespace:="http://tempuri.org/")> _
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<ScriptService()> _
Public Class ServiceBridge
  Inherits System.Web.Services.WebService

  <WebMethod()> _
  Public Function GetAddressByPostnum(ByVal postnum As String) As String

    Dim result As String = Nothing

    Dim setting As ConnectionStringSettings = _
      ConfigurationManager.ConnectionStrings("MyDB")
    Dim factory As DbProviderFactory = _
    DbProviderFactories.GetFactory(setting.ProviderName)

    Using db As DbConnection = factory.CreateConnection()
      db.ConnectionString = setting.ConnectionString
      Dim comm As DbCommand = factory.CreateCommand()

      ' postnumパラメータをキーに住所情報を検索
      comm.CommandText = _
        "SELECT prefecture, city, other FROM Address WHERE postnum=@postnum"
      comm.Connection = db
      Dim param As DbParameter = factory.CreateParameter()
      param.ParameterName = "@postnum"
      param.Value = postnum
      comm.Parameters.Add(param)
      db.Open()
      Dim reader As DbDataReader = comm.ExecuteReader()

      ' 取得した県、市、そのほかの情報を連結し、戻り値を生成
      If reader.Read() Then
        result =
          reader("prefecture") & reader("city") & reader("other")
      Else
        ' 合致するレコードが存在しない場合は例外をスロー
        Throw New Exception("該当するデータが存在しません。")
      End If
    End Using
    Return result
  End Function
End Class
郵便番号をキーに対応する住所を検索するためのXML Webサービス・クラス(ServiceBridge.asmx)(上:C#、下:VB)

 サンプル・アプリケーションの大まかな流れについては、コード内のコメントを参照していただくとして、ここで注目していただきたいのは、

「XML Webサービス・クラスにはScriptService属性を付与しなければならない」

という点だ。

 ScriptService属性(System.Web.Script.Services名前空間)は、該当のXML Webサービス・クラスがクライアント側スクリプトから呼び出し可能であるかどうかを表すものだ。ASP.NET AJAX経由で呼び出すことを想定したXML Webサービス・クラスでは、必ずScriptService属性を付与する必要がある。

 逆に、この一点を除いては、特別にASP.NET AJAXを意識したコードを記述する必要はない。一般的なXML Webサービス・クラスを記述するのと同じ要領で、ロジックを記述することが可能だ(なお、ここではXML Webサービス・クラスそのものの記法については割愛する。詳細については、「ASP.NETを使用したXML Webサービス」などを参照していただきたい)。

 以上を理解したら、さっそく、XML Webサービス・クラスの動作をテスト・ページから確認してみよう。テスト・ページを起動するには、Visual Studio 2005を使っているならば、ソリューション・エクスプローラから.asmxファイルを選択した状態で[デバッグ開始]ボタンをクリックすればよい。

「GetAddressByPostnum」リンクをクリック
パラメータ値を入力して[起動]ボタンをクリック
ServiceBridge.asmxのテスト・ページ
XML Webサービス・クラスで提供されるサービス・メソッドの一覧が表示されるので、テストしたいメソッドを選択する。必要なパラメータを入力したうえで[起動]ボタンをクリックする。

 上のようなテスト・ページが起動し、クラス内で公開されているサービス・メソッドの一覧が表示されるはずだ。ここからテストしたいメソッドを選択すると、メソッド起動のためのページが表示されるので、必要なパラメータ(ここでは郵便番号)を入力したうえで[起動]ボタンをクリックすればよい。

 新規のウィンドウが開き、以下のようにサービス・メソッドの処理結果(戻り値とそのデータ型など)をXML形式で確認できれば成功だ。

GetAddressByPostnumメソッドのテスト結果
サービス・メソッドの処理結果(戻り値とそのデータ型など)をXML形式で確認できる。

[注意]

後日公開予定の「TIPS:[ASP.NET AJAX]サービス・ブリッジ機能で構造化データを受け渡しするには?(応用編)」であらためて詳述するが、ASP.NET AJAXからの呼び出し時には、ブリッジ機能により.asmxファイルは(デフォルトで)JSON形式による応答を行う。そうした意味では、テスト・ページで確認できる結果はブリッジ機能を経由しておらず、ASP.NET AJAXの通信で流れるそれとは一致しないので、注意すること。

 後日公開予定の「TIPS:[ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(クライアントサイド編)」で、本稿で作成したサービス・メソッドをクライアントサイド・スクリプトから実行する方法を紹介する。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:Webフォーム 処理対象:ASP.NET AJAX
関連TIPS:[ASP.NET AJAX]ASP.NET AJAX経由でユーザー認証を行うには?(後日公開予定)
関連TIPS:[ASP.NET AJAX]ASP.NET AJAXからユーザー・プロファイル機能を利用するには?(後日公開予定)
関連TIPS:[ASP.NET AJAX]サービス・ブリッジ機能で構造化データを受け渡しするには?(応用編)(後日公開予定)
関連TIPS: [ASP.NET AJAX]クライアントサイド・スクリプトからXML Webサービスを非同期呼び出しするには?(クライアントサイド編)(後日公開予定)

この記事と関連性の高い別の.NET TIPS
[ASP.NET AJAX]Webサービス・ブリッジ機能により構造化データを受け渡しするには?(基本編)
[ASP.NET AJAX]ダイナミック・コンテキスト機能でポップアップ・コントロールの内容を動的に生成するには?
[ASP.NET AJAX]DynamicPopulateコントロールでXML Webサービスを非同期に呼び出すには?
[ASP.NET AJAX]クライアントサイド・スクリプトからカスタムの認証機能を利用するには?
[ASP.NET AJAX]クライアントサイド・スクリプトからASP.NETの認証機能を利用するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム 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 記事ランキング

本日 月間