AJAXが主流になってきている昨今である。サーバ側のコードだってJavaScriptから簡単に呼び出せるようにしてくれたのがMicrosoftのAJAXだ。利点はPostBackをせずに、つまり、ページのリフレッシュをせずに動的にHTMLの要素を表示し、ユーザの使い勝手をよくしようとするものだ。この記事ではウェブサービスから返されたHTMLの文字列をJavaScriptで読み込み、それを動的に表示する方法を簡単な例で紹介する。

まずはASP .NETのプロジェクトに.asmxのファイルを追加する。ウェブサービスだからといって別途ウェブサービスのプロジェクトを用意する必要はない。この例ではSimpleService.asmxと名前をつける。そして下のようにコードを書く。

   1:  Imports System.Web.Services
   2:  Imports System.Web.Services.Protocols
   3:  Imports System.ComponentModel
   4:  Imports System.Web.UI.HtmlControls
   5:  Imports System.IO
   6:  Imports System.Text
   7:   
   8:  ' To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
   9:  ' <System.Web.Script.Services.ScriptService()> _
  10:  <System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
  11:  <System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
  12:  <ToolboxItem(False)> _
  13:  <System.Web.Script.Services.ScriptService()> _
  14:  Public Class SimpleService
  15:      Inherits System.Web.Services.WebService
  16:   
  17:      <WebMethod()> _
  18:      Public Function GetHtml() As String
  19:          ' まずはクライアント側に返したいHTMLをSystem.Web.UI.HtmlControlsにあるクラス群を使って作成する。
  20:          Dim cell1 As New HtmlTableCell()
  21:          cell1.InnerText = "Hello Cell1"
  22:   
  23:          Dim row1 As New HtmlTableRow()
  24:          row1.Cells.Add(cell1)
  25:   
  26:          Dim table As New HtmlTable()
  27:          table.Rows.Add(row1)
  28:          table.Border = 1
  29:   
  30:          ' ここからHTMLコントロールを文字列に変えるプロセス。
  31:          Dim sb As New StringBuilder()
  32:          Dim sw As New StringWriter(sb)
  33:          Dim htmlWriter As New HtmlTextWriter(sw)
  34:   
  35:          table.RenderControl(htmlWriter)
  36:   
  37:          Return sb.ToString()
  38:   
  39:      End Function
  40:   
  41:  End Class

 

上のコードをもうちょっと解説する。13行目のSimpleServiceクラスに対するAttributeは追加してやらなければいけません。これはJavaScriptから呼び出すことを可能にしますよというAttributeだ。そしてGetHtmlというFunctionを作成しStringを返すようにしてやる。もちろんWebMethodのAttributeをつけてやるのも忘れないようにする。そしてTableを作成してHtmlTableのオブジェクトをRenderControlというメソッドを実行するとStringBuilderにそのHTMLが入っているのでそれを返してやるだけだ。これでウェブサービスの準備は完了だ。

次にクライアント側だ。ASP.NETのプロジェクトを作成するとDefalt.aspxがついてくるのでそれを使う。

ASP.NETでAJAXを使うには必ずそのページにScriptManagerを追加してやらなければならない。これはformタグ内に入れてやるといい。そのScriptManager内にはServicesというコレクションが存在し、そこに先ほど書いたSimpleService.asmxへの参照を追加してやる。

<asp:ScriptManager runat="server" ID="ScriptManager1">

    <Services>

        <asp:ServiceReference Path="~/SimpleService.asmx" />

    </Services>

</asp:ScriptManager>

これでウェブサービスを直接JavaScriptから呼び出せる。

Default.aspxにHTMLボタンを貼り付けてそのonclickのイベントハンドラーで次のようなJavaScriptを書く。

function Button1_onclick() {
    AjaxTest.SimpleService.GetHtml(OnComplete, OnTimeOut, OnError);
    return true;
}

実際にコードをVS2008上で書いてみるとJavaScriptのインテリセンスが表示されるので便利だ。通常はJavaScriptからウェブサービスへのコールは非同期で行われるので上のようなコードになる。それではOnCompleteを見てみよう。

function OnComplete(arg)
{
    alert(arg);
    var divLayer = document.getElementById("divHtmlPlaceHolder");
    divLayer.innerHTML = arg;
}

ここではウェブサービスから受け取ったHTMLを一度alertで表示させて既存のdivタグ内(divHtmlPlaceHolder)に入れてやるのだ。OnErrorとOnTimeOutも下に貼り付けておこう。

function OnTimeOut(arg)
{
    alert("Call timed out");

}

function OnError(arg)
{
    alert("Error happened");
}

 

これで簡単にサーバ側のコードがJavaScript側から呼び出せる。

更新:Fiddler2でHTMLトラフィックを見てみました。Responseはこんな感じです。XMLを使わずコンパクトでいいんじゃないでしょうか。

HTTP/1.1 200 OK

Cache-Control: private, max-age=0

Content-Type: application/json; charset=utf-8

Server: Microsoft-IIS/7.0

X-AspNet-Version: 2.0.50727

X-Powered-By: ASP.NET

Date: Sun, 27 Jul 2008 23:47:37 GMT

Content-Length: 153

{"d":"\u003ctable border=\"1\"\u003e\r\n\t\u003ctr\u003e\r\n\t\t\u003ctd\u003eHello Cell1\u003c/td\u003e\r\n\t\u003c/tr\u003e\r\n\u003c/table\u003e\r\n"}

コメント書き込み