ホーム > 実験室 > 休日情報 Web サービス > ASP.NET AJAX からの使い方 このエントリーを含む はてなブックマーク 0 users

休日情報 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 を開いて、以下の内容を追加してください。

  1. using ステートメントを追加します: using System.Web.Script.Services;
  2. クラスに ScriptService 属性を追加します: [ScriptService] public class PublicHodliayJP : ...
  3. クラスに 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 クラスの配列です。

このページに寄せられたコメント

このページにはまだコメントが投稿されていません。

コメントしてください:
お名前: (半角/全角問わず 16 文字まで)
コメント:
(no HTML)
確認:
このテキストボックスに "確認" の 2 文字を書くと投稿できるようになります。
投稿ボタンが自動的に有効にならない場合は、ここをクリックしてください
これは、自動的にスパムコメントを書き込もうとする悪意をもったプログラムと、 そうでないあなたを識別するためのものです。お手数をおかけしますがよろしくお願いします。 また、ブラウザによっては対応していない場合があるかも知れません。IE 7 と Firefox で動作確認を行いました。

このページに寄せられたトラックバック

このページはまだトラックバックを受信していません。

このページへのトラックバック Ping URL:
http://bearmini.net/trackback.aspx?~/publicholidays/usefromaspdotnetajax.aspx

このサイトの上位人気記事