休日情報 Web サービス - ASP.NET AJAX からの使い方
ASP.NET 2.0 の Web ページから ASP.NET AJAX を介して当 Web サービスを使用する方法を解説します。
いわゆる "Mush-up" というやつです。
bearmini.net の publicholidays Web サービスは ASP.NET 2.0 で作成されていますので、ASP.NET AJAX を使用すれば簡単に呼び出すことが出来てしまいそうですが、クロスサイトスクリプティングを防ぐ目的からか、他のサイトの JavaScript からは直接呼び出すことが出来ません。
そこで、あなたのサイト上に "プロキシ" Web サービスを作成し、そのプロキシ Web サービスをあなたのページの JavaScript から呼び出します。
使用する ASP.NET AJAX のバージョンは RC です。
私の環境では Visual Studio 2005 Professional Edition を使用していますので、説明文中のメニュー構成などは他のエディションと異なる場合があるかも知れません。その場合は適宜読み替えてください。
サンプルプログラム PublicHolidaySample_Ajax.zip
ステップ 0. 準備
まずは ASP.NET AJAX が使える Web ページを作成します。
すでに ASP.NET AJAX が使える Web ページがある場合は次のステップに進んでください。
Visual Studio 2005 のメインメニューから「ファイル」-「新規作成」-「Web サイト...」と選択してください。
「新しい Web サイト」というダイアログが出てくるはずです。
ASP.NET AJAX がインストールされていれば、「ASP.NET AJAX-Enabled Web Site」という項目があるはずですので、それを選択します。
保存場所などは適当に決めてください。
新しい Web サイトが作成されたら Default.aspx を開きます。
ステップ 1. ターゲット Web サービスの参照を追加する
まず、本当に呼び出したいほうの Web サービス(便宜上、ターゲット Web サービスと呼びます)の参照をあなたの Web サイトに追加します。
Visual Studio 2005 のメインメニューから [Web サイト] - [Web 参照の追加] を選択します。
[Web 参照の追加] ダイアログが現れますので、[URL] 欄に http://bearmini.net/publicholidays/JP.asmx?WSDL と入力し [移動] ボタンを押します。
[この URL で見つかったサービス] という欄に [1 個のサービスが見つかりました:-JP] と表示されるはずです。
[参照の追加] ボタンを押してください。
ステップ 2. ターゲット Web サービスを呼び出すためのプロキシ Web サービスを作成する
次に、ターゲット Web サービスを呼び出すためのプロキシ Web サービスをあなたのサイトに追加します。
Visual Studio 2005 のメインメニューから [ファイル] - [新規作成] - [ファイル...] を選択してください。
[Web サービス] を選択し、適当な名前をつけて保存します。
ここからは PublicHolidayJP.asmx という名前をつけたものとして話を進めます。
作成された PublicHolidayJP.asmx のコードビハインドファイルである App_Code/PublicHolidayJP.cs を開いて、以下の内容を追加してください。
- using ステートメントを追加します: using System.Web.Script.Services;
- クラスに ScriptService 属性を追加します: [ScriptService] public class PublicHodliayJP : ...
- クラスに IsPublicHoliday() メソッドを追加します
[WebMethod]
public bool IsPublicHoliday(int y, int m, int d)
{
net.bearmini.bearmininetpublicholidaysJP ws = new net.bearmini.bearmininetpublicholidaysJP();
return ws.IsPublicHoliday(y, m, d);
}
ステップ 3. ScriptManager にプロキシ Web サービスへの参照を追加する
ステップ 0 で新規に Web サイトを作成した場合は Default.aspx のソースを開いてください。既存のサイトの Web ページで Web サービスを使用したい場合はそのページのソースを開きます。
その中に、<asp:ScriptManager> というタグがあると思います。
その <asp:ScriptManager> タグの中に以下のように <Services> タグおよび <asp:ServiceReference> タグを書いてください。
<asp:ScriptManager 〜〜>
<Services>
<asp:ServiceReference Path="PublicholidayJP.asmx" />
</Services>
</asp:ScriptManager>
<asp:ServiceReference> タグの Path 属性はあなたがプロキシ Web サービスにつけた名前に適宜置き換えてください。
asp:ScriptManager タグがもともと空タグだった場合(/> で終わっていた場合)、/ (スラッシュ)を消し、その後ろに </asp:ScriptManager> を追加してから参照先を追加しましょう。
ステップ 4. Web サービスの呼び出し
ここまできたら、いよいよターゲット Web サービス(http://bearmini.net/publicholidays/JP.asmx)を呼び出すことができます。
呼び出し元 Web ページの form タグの中に以下の内容をコピー&ペーストしてください。
IsPublicHoliday()<br />
<input type="text" id="textYear1" />年
<input type="text" id="textMonth1" />月
<input type="text" id="textDay1" />日
<input type="button" value="call" onclick="return testIsPublicHoliday();" /><br />
結果: <span id="result1"></span>
<script type="text/javascript">
function testIsPublicHoliday()
{
var y = $get('textYear1').value;
var m = $get('textMonth1').value;
var d = $get('textDay1').value;
PublicHolidayJP.IsPublicHoliday(y, m, d, OnComplete_IsPublicHolidayJP, OnError_IsPublicHolidayJP);
$get('result1').innerText = "サービスを呼び出し中...";
}
function OnComplete_IsPublicHolidayJP(result)
{
$get('result1').innerText = result;
}
function OnError_IsPublicHolidayJP(result)
{
$get('result1').innerText = "エラーが発生しました: ";
$get('result1').innerText += result.get_message() + ", " + result.stackTrace();
}
</script>
保存して実行してみましょう。
テキストボックスに適当な年月日(1948年〜2050年の間)を入力して、call ボタンを押してみましょう。
結果:のところに true か false と表示されましたか?
ほかのメソッドも呼び出す
publicholidays/JP Web サービスは、IsPublicHoliday() 以外にも GetPublicHolidayNames(), GetPublicHolidaysByMonth(), GetPublicHolidaysByYear() というメソッドを提供しています。
これらも呼び出すことができるように、プロキシ Web サービスクラスに以下のメソッドを追加します。
[WebMethod]
public net.bearmini.HolidayName[] GetPublicHolidayNames(int y, int m, int d)
{
net.bearmini.bearmininetpublicholidaysJP ws = new net.bearmini.bearmininetpublicholidaysJP();
return ws.GetPublicHolidayNames(y, m, d);
}
[WebMethod]
public net.bearmini.HolidayInfo[] GetPublicHolidaysByMonth(int y, int m)
{
net.bearmini.bearmininetpublicholidaysJP ws = new net.bearmini.bearmininetpublicholidaysJP();
return ws.GetPublicHolidaysByMonth(y, m);
}
[WebMethod]
public net.bearmini.HolidayInfo[] GetPublicHolidaysByYear(int y)
{
net.bearmini.bearmininetpublicholidaysJP ws = new net.bearmini.bearmininetpublicholidaysJP();
return ws.GetPublicHolidaysByYear(y);
}
つづいて適当な名前のファイル(拡張子は .aspx)を新規作成して以下の内容を貼り付けて保存し、実行してみて下さい。
他の関数もテストすることができます。
<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>PublicHoliday Web サービスのテスト</title>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="PublicHolidayJP.asmx" />
</Services>
</asp:ScriptManager>
</head>
<body>
<form id="form1" runat="server">
<div>
IsPublicHoliday()<br />
<input type="text" id="textYear1" />年
<input type="text" id="textMonth1" />月
<input type="text" id="textDay1" />日
<input type="button" value="call" onclick="return testIsPublicHoliday();" /><br />
結果: <span id="result1"></span>
<script type="text/javascript">
function testIsPublicHoliday()
{
var y = $get('textYear1').value;
var m = $get('textMonth1').value;
var d = $get('textDay1').value;
PublicHolidayJP.IsPublicHoliday(y, m, d, OnComplete_IsPublicHolidayJP, OnError_IsPublicHolidayJP);
$get('result1').innerText = "サービスを呼び出し中...";
}
function OnComplete_IsPublicHolidayJP(result)
{
$get('result1').innerText = result;
}
function OnError_IsPublicHolidayJP(result)
{
$get('result1').innerText = "エラーが発生しました: ";
$get('result1').innerText += result.get_message() + ", " + result.stackTrace();
}
function OnAborted_IsPublicHolidayJP(result)
{
$get('result1').innerText = "Web サービス呼び出しが中止されました";
}
</script>
<hr />
GetPublicHolidayNames()<br />
<input type="text" id="textYear2" />年
<input type="text" id="textMonth2" />月
<input type="text" id="textDay2" />日
<input type="button" value="call" onclick="return testGetPublicHolidayNamesJP();" /><br />
結果: <span id="result2"></span>
<script type="text/javascript">
function testGetPublicHolidayNamesJP()
{
var y = $get('textYear2').value;
var m = $get('textMonth2').value;
var d = $get('textDay2').value;
PublicHolidayJP.GetPublicHolidayNames(y, m, d, OnComplete_GetPublicHolidayNamesJP, OnError_GetPublicHolidayNamesJP);
$get('result2').innerText = "サービスを呼び出し中...";
}
function OnComplete_GetPublicHolidayNamesJP(result)
{
if ((result == null) || (result[0] == null) || (result[0].value == null))
{
$get('result2').innerText = "(休日ではありません)";
return;
}
$get('result2').innerText = result[0].value;
}
function OnError_GetPublicHolidayNamesJP(result)
{
$get('result2').innerText = "エラーが発生しました";
$get('result2').innerText += result.get_message() + ", " + result.stackTrace();
}
</script>
<hr />
GetPublicHolidaysByMonth()<br />
<input type="text" id="textYear3" />年
<input type="text" id="textMonth3" />月
<input type="button" value="call" onclick="return testGetPublicHolidaysByMonth();" /><br />
結果: <span id="result3"></span>
<script type="text/javascript">
function testGetPublicHolidaysByMonth()
{
var y = $get('textYear3').value;
var m = $get('textMonth3').value;
PublicHolidayJP.GetPublicHolidaysByMonth(y, m, OnComplete_GetPublicHolidaysByMonth, OnError_GetPublicHolidaysByMonth);
$get('result3').innerText = "サービスを呼び出し中...";
}
function OnComplete_GetPublicHolidaysByMonth(result)
{
$get('result3').innerText = "";
for (var i = 0; i < result.length; i++)
{
var h = result[i];
$get('result3').innerText += h.Year + '/' + h.Month + '/' + h.Day + '(' + h.HolidayNames[0].value + ')';
if (i < result.length - 1)
{
$get('result3').innerText += ',';
}
}
}
function OnError_GetPublicHolidaysByMonth(result)
{
$get('result3').innerText = "エラーが発生しました";
$get('result3').innerText += result.get_message() + ", " + result.stackTrace();
}
</script>
<hr />
GetPublicHolidaysByYear()<br />
<input type="text" id="textYear4" />年
<input type="button" value="call" onclick="return testGetPublicHolidaysByYear();" /><br />
結果: <span id="result4"></span>
<script type="text/javascript">
function testGetPublicHolidaysByYear()
{
var y = $get('textYear4').value;
PublicHolidayJP.GetPublicHolidaysByYear(y, OnComplete_GetPublicHolidaysByYear, OnError_GetPublicHolidaysByYear);
$get('result4').innerText = "サービスを呼び出し中...";
}
function OnComplete_GetPublicHolidaysByYear(result)
{
$get('result4').innerText = "";
for (var i = 0; i < result.length; i++)
{
var h = result[i];
$get('result4').innerText += h.Year + '/' + h.Month + '/' + h.Day + '(' + h.HolidayNames[0].value + ')';
if (i < result.length - 1)
{
$get('result4').innerText += ',';
}
}
}
function OnError_GetPublicHolidaysByYear(result)
{
$get('result4').innerText = "エラーが発生しました";
$get('result4').innerText += result.get_message() + ", " + result.stackTrace();
}
</script>
</div>
</form>
</body>
</html>
補足
GetPublicHolidayNames() 関数は、HolidayName というクラスの配列を返します。
HolidayName クラスは lang と value というメンバを持っています。
たとえば GetPublicHolidayNames(2006, 1, 1) という引数で呼び出した場合、
result[0].lang == "ja"
result[0].value == "元日"
result[1].lang == "en"
result[1].value == "New Year's Day"
という具合に値が入っています。
同様に GetPublicHolidaysByMonth() 関数および GetPublicHolidaysByYear() 関数は、HolidayInfo というクラスの配列を返します。
HolidayInfo クラスは Year と Month と Day そして HolidayNames というメンバを持っています。
Year, Month, Day はそれぞれ int 型、HolidayNames は HolidayName クラスの配列です。
このページに寄せられたトラックバック
このページはまだトラックバックを受信していません。
このページへのトラックバック Ping URL:
http://bearmini.net/trackback.aspx?~/publicholidays/usefromaspdotnetajax.aspx