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


 ASP.NET AJAX
[ASP.NET AJAX] JavaScript の pageLoad 関数と pageUnload 関数
By : Akira INOUE   Date : 2007/08/30 21:00

@IT の Insider.NET 会議室でこんな投稿
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=40926&forum=7&3
があったので、少しだけフォローしておきます。

ASP.NET AJAX では、クライアントの JavaScript に pageLoad または pageUnload という名前の関数があった場合、ページのロード時およびアンロード時に必ず実行されるようになっています。

Script.js

// ページロード
function pageLoad()
{
  $get("output").innerHTML += "ページロード<br />";
}

// ページアンロード
function pageUnload()
{
  alert("ページ アンロード");
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

Default.aspx

<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" >
      <Scripts>
        <asp:ScriptReference Path="Script.js" />
      </Scripts>
    </asp:ScriptManager>
    <hr />
    <div id="output"></div>
  </form>
</body>

とくに <body onload="pageLoad()"> などと onload イベントを記述する必要はありません。
記述してしまうと、pageLoad 関数が2回実行されることになりますので注意が必要です。

【上記コードの実行結果】
fig1.jpg

 

また、ページのロードイベントおよびアンロードイベントは Sys.Application.add_load および Sys.Application.add_unload メソッドで任意の関数をイベントハンドラとして指定できますが、暗黙的に実行される pageLoad 関数と pageUnload 関数の実行順序は以下のようになります。

【ページロード時】
1. Sys.Application.add_load メソッドで追加した任意の関数
2. pageLoad 関数

【ページアンロード時】
1. pageUnload 関数
2. Sys.Application.add_unload メソッドで追加した任意の関数


なお、pageLoad 関数などのページロードイベントハンドラは、UpdatePanel によるページの部分更新でも実行されることに注意してください。
この場合には、pageLoad 関数の第2引数で渡される Sys.ApplicationLoadEventArgs オブジェクトのプロパティから、ページ全体の更新による呼び出しなのか、部分更新による呼び出しかを判別することが出来ます。

Script.js

// ページロード
function pageLoad(sender, /*Sys.ApplicationLoadEventArgs*/ args)
{
  $get("output").innerHTML += "ページロード( " +
                              "isPartialLoad = " +
                              args.get_isPartialLoad() + " )<br />";
}

if (typeof(Sys) !== "undefined") Sys.Application.notifyScriptLoaded();

Default.aspx

<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" >
      <Scripts>
        <asp:ScriptReference Path="Script.js" />
      </Scripts>
    </asp:ScriptManager>

    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
      <ContentTemplate>
        <asp:Button ID="Button1" runat="server" Text="Button" /><br />
        <asp:Label ID="Label1" runat="server">
          <% = DateTime.Now.ToString() %>
        </asp:Label>
      </ContentTemplate>
    </asp:UpdatePanel>

    <hr />
    <div id="output"></div>
  </form>
</body>

【上記コードの実行結果】
fig2.jpg

 

まだまだ日本語の情報が少なく英語の情報になりますが、以下に詳しく解説されていますので参考にしてみてください。

「ASP.NET AJAX Client Life-Cycle Events」
http://www.asp.net/AJAX/Documentation/Live/overview/AJAXClientEvents.aspx

 


AJAX Control Toolkit (.NET Framework 3.5 版) Release
By : Akira INOUE   Date : 2007/07/27 18:13

.NET Framework 3.5 Beta 2 と Visual Studio 2008 Beta 2 のリリースにあわせて、AJAX Control Toolkit の .NET Framework 3.5 版 がリリースされています。

AJAX Control Toolkit Release
http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4923

.NET Framework 2.0 の環境では、これまで通りで更新はされていませんが、.NET Framework 3.5 の環境用に

AjaxControlToolkit-Framework3.5.zip
AjaxControlToolkit-Framework3.5-NoSource.zip

の2つのダウンロードが追加されています。

Visual Studio 2008 Beta 2 (.NET Framework 3.5 Beta 2) の環境では、こちらを使用しましょう。


ちなみに、ASP.NET Official サイト ( http://asp.net/ ) もデザインが一新されています。

 


Web Development Helper 0.8.5.0 Release
By : Akira INOUE   Date : 2007/07/25 10:34

Web Development Helper がバージョンアップされてます。

Web Development Helper 0.8.5.0 (2007/07/24 Release)
http://projects.nikhilk.net/Projects/WebDevHelper.aspx

Nikhil Kothari's Weblog
http://www.nikhilk.net/WebDevHelperScriptBrowser.aspx

新機能として、Script Class Browser が追加されています。

0.8.5.0: Added Script Class Browser for Microsoft ASP.NET AJAX pages

クラスブラウザの JavaScript 版というところですね。
ちょっとだけ使ってみましたが便利かも。

 


ScriptDoc 1.0 リリース
By : Akira INOUE   Date : 2007/07/05 10:24

ScriptDoc という、JavaScript コードに書かれた XML コメント(C# と同じフォーマット)から XML ドキュメントを生成するツールがリリースされています。

ScriptDoc 1.0
http://www.codeplex.com/scriptdoc
[2007/06/27 Release]

ScriptDoc 1.0 available
http://weblogs.asp.net/bleroy/archive/2007/06/27/scriptdoc-1-0-available.aspx

今後、JavaScript を書く機会が増えてきそうな感じなので、要チェックです。
近いうちに試してみます。

 


[AJAX Control Toolkit] AnimationExtender に見るダイナミックプロパティの実装
By : Akira INOUE   Date : 2007/06/21 11:55

ASP.NET AJAX Control Toolkit の AnimationExtender には DiscreteAnimation というクラスがあります。このアニメーションは、指定したプロパティに、配列として渡したプロパティ値を一定の時間内で順に適用するものです。

この Discrete アニメーションを調べていて、XML 記述で Values 属性値にどのように値の配列を渡すのかがわかりませんでした。

ドキュメントをみても、
http://ajax.asp.net/ajaxtoolkit/Walkthrough/AnimationReference.aspx#DiscreteAnimation

Array values;
Array of possible values of the property that will be iterated over as the animation is played.

としか書いていないし・・・

以下のように、JSON, カンマ, セミコロン などを試しましたが当然NG。

<%-- JSON 記述 ( NG ) --%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
  Values="['white', 'lightskyblue', 'royalblue', 'blue', '#ffb6c1']" />

<%-- カンマ ( NG ) --%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
  Values="'white', 'lightskyblue', 'royalblue', 'blue', '#ffb6c1'" />

<%-- セミコロン ( NG ) --%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
  Values="'white'; 'lightskyblue'; 'royalblue'; 'blue'; '#ffb6c1'" />


ということで、Discrete Animation で検索してみたところ、US の ASP.NET Forums に答えが出ていました。
http://forums.asp.net/p/1108530/1705424.aspx

MSの方の回答で、Values 属性でなくて ValuesScript 属性を使って JSON 記述で記述するとのこと。

<%-- ValuesScript を使って JSON 記述 ( OK! )--%>
<Discrete Property="style" PropertyKey="backgroundColor" Duration="5.0"
  ValuesScript="['white', 'lightskyblue', 'royalblue', 'blue', '#ffb6c1']" />

うおーっ、こんな裏技が隠されていたのか!!と驚愕(ドキュメントに書いてよー)。

ということで、この ValuesScript がどんな実装をしているかを早速調べてみたら、そこからは新たな事実が・・・

それは、

ダイナミックプロパティ ( Dynamic Properties ) というものの存在でした。

通常のプロパティ(属性)は、Animation オブジェクトの生成時に静的に値が決まってしまいますが、ダイナミックプロパティは、アニメーションの開始時( onStart メソッド実行時)に、その値が動的に評価され設定されるとのこと。

ダイナミックプロパティかどうかの判別は、プロパティ(属性)名の接尾辞(suffix)が "script" かどうかで決まります。また、ダイナミックプロパティの場合、その値は JavaScript の eval 関数で評価されます。

つまり、プロパティ(属性)名の終わりに script を付ければ、値に JavaScript が記述できるのです!

たまたま、Discrete Animation の ValuesScript でこのダイナミックプロパティの存在を知りましたが、AnimationExtender の他のアニメーションのプロパティにも応用可能です。

例えば、Duration プロパティのかわりに DurationScript を使って、テキストボックスから値を取得することも出来ます。

<%-- Panel1 のフェードイン、移動、リサイズの並列実行 --%>
<Parallel AnimationTarget="Panel1"
  DurationScript="(isNaN($get('Text1').value)) ? 0 : $get('Text1').value;">
  <FadeIn />
  <Move Horizontal="80" Vertical="120" Unit="px" />
  <Resize Width="300" Height="300" Unit="px" />
</Parallel>

このダイナミックプロパティ、他のアニメーションを見ていくと、

  • Script Action の script プロパティ
  • Condition Animation の conditionScript プロパティ
  • Case Animation の selectScript プロパティ

などでも使われていますね。

AnimationExtender を使うにあたって、状況によっては利用価値がありそうですので、覚えておいて損はないでしょう。

以下、簡単にダイナミックプロパティ ( Dynamic Properties ) の実装の抜粋を記しておきます。

●Animations.js

$AA.createAnimation = function(obj, defaultTarget) {

  for (var property in obj) {

    var prop = property.toLowerCase();

    ...(中略)...

    // Try to set the value of a dynamic property
    if (prop.endsWith('script')) {
      setter = properties[prop.substr(0, property.length - 6)];
      if (setter && String.isInstanceOfType(setter) && animation[setter]) {
        animation.DynamicProperties[setter] = value;
      }
    }

    ...(中略)...
}

onStart : function() {

  ...(中略)...

  // Initialize any dynamic properties
  for (var property in this.DynamicProperties) {
    try {
      // Invoke the property's setter on the evaluated expression
      this[property](eval(this.DynamicProperties[property]));
    } catch(ex) {
      ...(中略)...
    }
  }
},


※この実装から見ると、プロパティ(属性)名の大文字小文字は関係ないようですね。疑問がさらに1つ解決です。

 


[AJAX Control Toolkit] Version 1.0.10618.0 がリリース
By : Akira INOUE   Date : 2007/06/19 14:12

ASP.NET AJAX Control Toolkit リフレッシュリリースが出ています。

ASP.NET AJAX Control Toolkit Version 1.0.10618.0 ( 2007/06/18 Release )
http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=4923

  • Tabs: Resolved NamingContainer issues so that FindControl works as expected in Tabs.
  • ToolkitScriptManager: Shorter combined script URLs and new HTTP handler support for generation of combined script files.
  • Dependencies: Removed explicit reference to VsWebSite.Interop.dll and stdole.dll. They will not be automatically included in the web configuration files by Visual Studio.
  • FilteredTextBox: Navigation, Control and Delete keys work fine in all browsers.
  • Localization: Turkish, Dutch, and Traditional and Simplified Chinese language support added.

バグ Fix と少しの改良がされている模様です。
これからインストールしてみます。

 


[AJAX Control Toolkit] ValidatorCalloutExtender などで Animations が追加されてます
By : Akira INOUE   Date : 2007/06/08 22:15

先日、新バージョンがリリースされた ASP.NET AJAX Control Toolkit ですが、いくつかのエクステンダでアニメーション効果を付加することができるようになっています。

例えば、下図

ValidatorCallout1.jpg

の ValidatorCalloutExtender では、次のように ValidatorCalloutExtender 要素の子要素として Animations 要素を追加して、AnimationExtender と同じ記述ができるようになっています。

<asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"
  ControlToValidate="TextBox1"
  ErrorMessage="<b>名前が未入力です。</b><br /><br />名前を入力してください。"
  Display="None">
</asp:RequiredFieldValidator>
<ajaxToolkit:ValidatorCalloutExtender ID="ValidatorCalloutExtender1"
runat="server"
  TargetControlID="RequiredFieldValidator1"
  HighlightCssClass="Highlight">
  <Animations>
    <OnShow>
      <Sequence>
        <HideAction Visible="true" />
        <Pulse Duration=".1" Iterations="2" />
      </Sequence>
    </OnShow>
    <OnHide>
      <Sequence>
        <FadeOut Duration=".1" />
      </Sequence>
    </OnHide>
  </Animations>
</ajaxToolkit:ValidatorCalloutExtender>


この場合は、図ではわかりませんが、ValidatorCallout による検証メッセージの表示時にポップアップを2回点滅させています。そしてポップアップが非表示になるときにはフェード効果を付加しています。

このようなアニメーション効果の機能が追加されたコントロールには、次のものがあるようです。

  • AutoCompleteExtender
  • DropDownExtender
  • HoverMenuExtender
  • ListSearchExtender
  • PopupControlExtender
  • ValidatorCalloutExtender

とりあえず、AutoCompleteExtender でのアニメーション効果は
http://ajax.asp.net/ajaxtoolkit/AutoComplete/AutoComplete.aspx
で確認できます。

お試しあれ。

 


[AJAX Control Toolkit] ScriptManager の代わりに ToolkitScriptManager が追加されました
By : Akira INOUE   Date : 2007/06/07 15:30

昨晩、ASP.NET AJAX Control Toolkit のサンプルサイト( http://ajax.asp.net/ajaxtoolkit/Default.aspx )に、急にアクセスできなくなっていたのでどうしたのかな?と思っていたところ、新しいバージョンがリリースされたようで、このためだったのかもしれません。

ASP.NET AJAX Control Toolkit ( 2007/06/06 Release )
http://www.codeplex.com/AtlasControlToolkit/Release/ProjectReleases.aspx?ReleaseId=1813

かなりのバグ Fix がされているようですが、取り急ぎ大きな変更点を1つご紹介。

ScriptManager が ToolkitScriptManager に置き換えられました

これまで、ASP.NET AJAX Extensions の ScriptManager が使われていましたが、これが AJAX Control Toolkit に新しく用意された ToolkitScriptManager に変更になりました。

NewToolkit3.jpg

これにより、例えば次のような CalendarExtender を使用したサイト

NewToolkit1.jpg

をロードした時に、これまでは次のような数多くの ScriptResource (JavaScript) がロードされていました。

NewToolkit2.jpg

これが、ToolkitScriptManager を使うことにより次のようにかなり削減されて、レスポンスの面で改善されたことがわかります。

NewToolkit4.jpg

 

これまでの AJAX Control Toolkit を使用していた Web サイトの場合は、まず、Bin フォルダのアセンブリ( AjaxControlToolkit.dll と関連リソース dll )を最新のものに置き換えます。

そして、aspx ファイルの

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

<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1"
runat="server" />

に変更します。


ちなみに、ツールボックスのコントロールのアイコンも新しくなってます。
ご参考までに。

NewToolkit5.jpg

 


[ASP.NET AJAX] Timer コントロールは UpdatePanel の外に配置しよう
By : Akira INOUE   Date : 2007/05/19 18:59

ASP.NET AJAX Extensions の Timer コントロールを使用する場合には、UpdatePanel コントロールの内部に配置すべきではないようです。

いくつか、UpdatePanel 内に Timer コントロールを配置してる例もありますが、可能なら Timer コントロールは UpdatePanel の外に配置して、UpdatePanel の Triggers コレクションで Timer の Tick イベントをトリガに設定しましょう

以下は、Timer を UpdatePanel 内に配置したサンプルです。

Timer1.jpg

aspxファイル

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
  Inherits="_Default" %>
<!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 runat="server">
  <title>TimerSample1CS</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
      <ContentTemplate>
        <asp:Timer ID="Timer1" runat="server" Interval="5000"
                                              OnTick="Timer1_Tick">
        </asp:Timer>
        <asp:Label ID="Label1" runat="server" Text="未更新"></asp:Label>
      </ContentTemplate>
    </asp:UpdatePanel>
    </div>
  </form>
</body>
</html>

C#コードビハインドファイル

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
 
public partial class _Default : System.Web.UI.Page
{
  protected void Page_Load(object sender, EventArgs e)
  {
  }

  protected void Timer1_Tick(object sender, EventArgs e)
  {
    Label1.Text = DateTime.Now.ToString();
  }
}

これを実行すると下図のように5秒間隔で時刻表示が更新されます(図ではちょっとわかりづらいですが)。

Timer2.jpg

ここで、5秒ごとにサーバとどのような通信がおこなわれているか見てみます。

ちなみに、ツールには Web Development Helper を使っています。
http://projects.nikhilk.net/Projects/WebDevHelper.aspx

Web Development Helper のログは以下のようになります。

Timer3.jpg

2回の Tick イベントによるサーバとの通信をキャプチャしていますが、1回の非同期ポストバックで2回の通信がおこなわれています

Default.aspx は当然ですが、その後の ScriptResource.axd?d=... は何でしょうか?
実はこれ、Microsoft AJAX Library の MicrosoftAjaxTimer.js という JavaScript ファイルです。

Timer コントロールは、サーバサイドで Sys.UI._Timer という JavaScript ライブラリに置き換えられ、クライアントサイドで実行されます。通常は、ページのロード時に1回だけスクリプトがダウンロードされれば済むわけですが、ここでは UpdatePanel 内に Timer コントロールを配置したことにより、UpdatePanel 内部のコントロールは非同期ポストバックで常にレンダリングされ、その対象に Timer コントロールも含まれてしまっているわけです。

これでも、更新間隔が非常に長かったり、負荷が問題にならない状況でしたら良いのでしょうが、なんか無駄ですよね。

この無駄をなくすには、次のように Timer コントロールを UpdatePanel の外に配置して、UpdatePanel の Triggers コレクションで Timer の Tick イベントをトリガに設定することで回避できます。

Timer4.jpg

aspxファイル

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
  Inherits="_Default" %>
<!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 runat="server">
  <title>TimerSample1CS</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div>
      <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
          <asp:Label ID="Label1" runat="server" Text="未更新"></asp:Label>
        </ContentTemplate>
        <Triggers>
          <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick" />
        </Triggers>

      </asp:UpdatePanel>
      <asp:Timer ID="Timer1" runat="server" Interval="5000"
                                            OnTick="Timer1_Tick">
      </asp:Timer>
    </div>
  </form>
</body>
</html>

Image5.jpg

今度は、Web Development Helper のログは以下のようになり、Default.aspx のみの通信となり、毎回 MicrosoftAjaxTimer.js ファイルがダウンロードされることがなくなりました。

Image6.jpg

この Timer コントロールは、Interval の単位がミリ秒だったりと(実際は1秒以下のポストバックは発生しないようですが)、サーバ負荷を十分考慮した設計をしないと、とんでもないことになりますので注意しましょう。

 


[ASP.NET AJAX] ASP.NET Futures の Managed JScript を試す
By : Akira INOUE   Date : 2007/05/17 11:24

ちょっと AJAX と XML-Script 関連で調べたいことがあったので、先日リリースされた ASP.NET Futures (May 2007) をインストールしてみました。

ツールボックスには、次のようなコントロール群が登録されます。

Futures0.jpg

 

また、Web サイトの新規作成では、テンプレートに

  • ASP.NET Futures AJAX Web Site
  • ASP.NET Futures Web Site
  • Dynamic Data Web Site

の3つが新たに登録されていました。

さらに、言語には

  • IronPython
  • Managed JScript

の2つが新たに出現(うおーっ!)。

Futures1.jpg

 

早速、Managed JScript やらを試してみました。

テンプレートには「ASP.NET Futures AJAX Web Site」を選択して、新規Webサイトを作成。

ソリューションには、次のようなファイルが現れました。

Futures2.jpg

拡張子 *.jsx が、Managed JScript のサーバサイドのスクリプトコードです。


とりあえず、よくあるパターンで TextBox, Label, Button, UpdatePanel を配置して・・・

Futures3.jpg

Default.aspx はこんな感じ。

<%@ Page Language="ManagedJScript" CodeFile="Default.aspx.jsx"
    Inherits="Microsoft.Web.Scripting.UI.ScriptPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
  <title>Untitled Page</title>
</head>
<body>
  <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <div>
   <asp:TextBox ID="TextBox1" runat="server" Width="250px"></asp:TextBox>
  <asp:UpdatePanel ID="UpdatePanel1" runat="server">
   <ContentTemplate>
    <asp:Label ID="Label1" runat="server" Width="250px"></asp:Label>
<br />
    <asp:Button ID="Button1" runat="server" Text="Click Me!" />
   </ContentTemplate>
  </asp:UpdatePanel>
 </div>
  </form>
</body>
</html>

Default.aspx.jsx はこんなコーディングをして、

function Page_Load(sender, e){
  if (Page.IsPostBack){
    Label1.Text = "Hello " + TextBox1.Text + " !!";
  }
}

さて、実行。

Futures4.jpg

ちゃんと動きました~。

#さて、本題をやらないと・・・


[AJAX Control Toolkit] Popup 関連のコントロールが IE 100%表示以外で位置がずれる
By : Akira INOUE   Date : 2007/04/09 11:25

ASP.NET 2.0 AJAX の応用として CodePlex にてリリースされている AJAX Control Toolkit には、多くの有用なコントロールが含まれています。

AJAX Control Toolkit
http://www.codeplex.com/AtlasControlToolkit

ただ、PopupControl 関連のコントロールには、現在のバージョン(2007-03-01 Release)では Internet Explorer のページ倍率を 100% 以外にすると、ポップアップウィンドウの表示位置がずれてしまい正しく表示されない不具合があるようです。

例えば、下記のページ
http://ajax.asp.net/ajaxtoolkit/Calendar/Calendar.aspx
の Calendar コントロール (CalendarExtender) のデモで試してみると、IE の表示倍率が 100% の場合はカレンダーが正しい位置にポップアップされます。

Cal100.jpg
Fig : CalendarExtender (IE 100% View)

しかし、例えば 125% 表示で試すと、カレンダーの表示位置が正しい位置より、より大きくオフセットされて表示されてしまいます。

Cal125.jpg
Fig : CalendarExtender (IE 125% View)

 

DropDown コントロール (DropDownExtender)
http://ajax.asp.net/ajaxtoolkit/DropDown/DropDown.aspx
でも、以下のようになってしまいます。

Drop100.jpg
Fig : DropDownExtender (IE 100% View)

 

Drop125thumb.jpg
Fig : DropDownExtender (IE 125% View)

正式に Fix されるまで、使用には注意が必要です。

 


[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   使用条件  プライバシー