検索 
2010年9月5日 ..:: ブログ ::..   ログイン


 ASP.NET AJAX
[ASP.NET AJAX] クライアントスクリプトからの Web サービスの非同期呼び出し
By : Akira INOUE   Date : 2007/03/28 20:31

ASP.NET AJAX をいろいろと調べていまして、そのメモを兼ねて一つ記事をアップします。

[The Official Microsoft ASP.NET 2.0 Site] にあるサンプル
「How Do I: ASP.NET AJAX Enable an Existing Web Service?」
http://www.asp.net/learn/videos/view.aspx?tabid=63&id=82

などでは、

function Button1_onclick() {
ret = SimpleService.SayHello(document.getElementById('Text1').value,
                             OnComplete, OnTimeOut, OnError);
return(true);
}

などと、Web メソッドの非同期呼び出しを記述しています。

幸いなこと(?)に JavaScript ではエラーとならずに実行されるのですが、正確にはこの記述は間違いです(以前の Atlas 時代の形式です)ので注意してください。

正確には、プロキシを使った Web サービスの呼び出しのプロトタイプは

myServiceProxy.MyServiceMethod(param1, ... , paramN,
               SucceededCallback, FailedCallback, userContext)

となっています。

参考:Generated Proxy Classes Web Service Methods
http://ajax.asp.net/docs/ClientReference/Sys.Net/GeneratedProxyClasses/
WebServiceMethods.aspx

サンプルのままだと、コールバック関数の OnComplete は問題ないのですが、タイムアウトでの処理のつもりで書いたコールバック関数 OnTimeOut がエラー発生時にも呼び出されてしまいます。

最新の ASP.NET AJAX では、タイムアウトとエラー発生時のコールバックは統一されており、同じ関数が呼び出されるようになっています(プロトタイプでは FailedCallback 引数に指定した関数)。

私は、このサンプルのデモムービーを見ていて、ちょっと混乱しました・・・


さて、参考までに・・・

ASP.NET AJAX を使って、クライアントサイドのスクリプトから Web サービスを呼び出すには、Web サービスのメソッドに System.Web.Script.Services 名前空間の ScriptService 属性 (ScriptServiceAttribute)が必要となります。

[ SimpleService.cs ]

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;

[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class SimpleService : System.Web.Services.WebService
{
  [WebMethod]
  public string SayHello(string name)
  {
    return "Hello : " + name;
  }
}

そして、aspx ソースに asp:ScriptManager を追加して、その子要素に Services/asp:ServiceReference を下記のように追加すると、Web サービスの呼び出しに必要な JavaScript プロキシコードが生成されます。

[ Default.aspx ]

<asp:ScriptManager runat="server" ID="scriptManager">
  <Services>
    <asp:ServiceReference Path="SimpleService.asmx" />
  </Services>
  <Scripts>
    <asp:ScriptReference Path="UsingSimpleService.js" />
  </Scripts>
</asp:ScriptManager>

生成されたプロキシスクリプトを使うと、クライアントサイドのスクリプトで Web サービスの非同期の呼び出しが、下記のコードのように簡単に行えるようになります。

[ UsingSimpleService.js ]

function pageLoad()
{
  SimpleService.set_timeout(3000);
  SimpleService.set_defaultUserContext("Default context");
  SimpleService.set_defaultSucceededCallback(SucceededCallback);
  SimpleService.set_defaultFailedCallback(FailedCallback);
}

function Button1_onclick()
{
  SimpleService.SayHello(document.getElementById("Text1").value);
}

function Button2_onclick()
{
  SimpleService.SayHello(document.getElementById("Text1").value,
                         SucceededCallback,
                         FailedCallback,
                         "User context");
}

function SucceededCallback(result, userContext, methodName)
{
  var text = result + " (" + userContext + ")" + " [" + methodName + "]";

  document.getElementById("Label1").innerText = text;
}

function FailedCallback(error, userContext, methodName)
{
  var text = "Service Error : " +  error.get_message() +
             " (" + userContext + ")" + " [" + methodName + "]";

  document.getElementById("Label1").innerText = text;
}

このプロキシを使った Web サービスの呼び出しでは、pageLoad で行っているように、プロキシの set_defaultXXXX メソッドで、コールバック関数を指定して Button1_onclick で Web サービスメソッドの呼び出しのみを行う方法と、Button2_onclick で行っているように Web サービスの呼び出し時にコールバック関数を指定することもできます。

ここで、プロキシを使った Web サービスの呼び出しのプロトタイプは前述のように

myServiceProxy.MyServiceMethod(param1, ... , paramN,
               SucceededCallback, FailedCallback, userContext);

となります。

また、各コールバック関数のプロトタイプは下記の通りとなります。

function SucceededCallback(result, userContext, methodName);
function FailedCallback(error, userContext, methodName);


ASP.NET AJAX は、UpdatePanel を使えばとても簡単に Web アプリケーションの AJAX 化ができるのですが、本格的な ASP.NET AJAX アプリケーションを作り始めると、やはりいろいろと奥が深いところがあり楽しいですね。

【参考】
Generated Proxy Classes
http://ajax.asp.net/docs/ClientReference/Sys.Net/GeneratedProxyClasses/default.aspx

 



MCAD


techbank.jp


Copyright © 2005-2008 by BitWiz   使用条件  プライバシー