Microsoft ASP.NET AJAXを使う †
ASP.NETでAjaxを使ったWebアプリケーションを作成する方法を前々号から紹介してきました。前回はICallbackEventHandlerインターフェイスを実装する方法を紹介し、JavaScriptを全て自分で記述する方法と比べ、多少楽をすることができました。それでもやはりJavaScriptのコードを自分で書くことは必要で、JavaScriptの知識が必要でした。
ここで紹介するMicrosoft ASP.NET AJAX(開発コード名"Atlas")を使用すれば、極端に言えば、自分でJavaScriptのコードを一行も書くことなく、Ajaxを使用したページを作成することができます。自分でJavaScriptのコードを書かなければならない場合でも、大幅に簡略化できます。
ASP.NET AJAXはマイクロソフトが公開している無料のフレームワークであり、ASP.NET 2.0に対応しています。現在最新のバージョンは1.0であり、ここで説明に使用しているASP.NET AJAXのバージョンも1.0です。
ASP.NET AJAXをインストールする †
ASP.NET AJAXをインストールするには.NET Framework 2.0が必要ですので、まず.NET Framework 2.0がインストールされていることを確認してください。
ASP.NET AJAXは「ASP.NET AJAX Downloads : The Official Microsoft ASP.NET 2.0 Site」からダウンロードできます。「ASP.NET 2.0 AJAX Extensions」と「ASP.NET AJAX Control Toolkit」がありますが、とりあえずはAJAX Extensionsだけで結構です。Control Toolkitをインストールする時も、AJAX Extensionsをインストールした後にしてください。
ダウンロードされたファイルは、"ASPAJAXExtSetup.msi"のようなファイル名になっているでしょう。このファイルをダブルクリックして、インストールを開始してください。インストールするには、管理者権限が必要です。また、前のバージョンのASP.NET AJAXがインストールされている場合は、アンインストールしてから新しいバージョンをインストールしてください。
ASP.NET AJAXのインストールに成功すると、Visual Studio 2005(またはVisual Web Developer Express Edition)にASP.NET AJAX用のプロジェクトのテンプレートがインストールされます。Visual Studioで「新しいWebサイト」ダイアログを表示させると、「ASP.NET AJAX-Enabled Web Site」というテンプレートが見つかるはずです。また、ツールボックスに「AJAX Extensions」というタブが追加され、幾つかのコンポーネントが登録されます。
ASP.NET AJAXを使用するには、Web.configに適切な設定が必要です。テンプレート「ASP.NET AJAX-Enabled Web Site」を使ってプロジェクトを作成したときは、適切なWeb.configが用意されるため問題ありません。
テンプレート「ASP.NET AJAX-Enabled Web Site」を使わなかった時でも、「AJAX Extensions」タブにあるコントロールをページに配置したときに、Web.configに必要な設定が書き込まれるということになっていますが、これが完全ではないようです。よって、テンプレート「ASP.NET AJAX-Enabled Web Site」で作成されるWeb.configを参考にして、自分で記述しないとエラーが出るかもしれません。
Visual Studioをインストールしていない場合は、Web.configの設定をすべて自分で書き込む必要があります。どのように記述するかのサンプルが、ASP.NET AJAXをインストールしたフォルダにあります。ASP.NET AJAXは、通常「C:\Program Files\Microsoft ASP.NET」のようなパスにインストールされ、サンプルのWeb.configはそれ以下の「C:\Program Files\Microsoft ASP.NET\ASP.NET 2.0 AJAX Extensions\v1.0.61025\web.config」のようなパスで見つかるでしょう。
UpdatePanelを使う †
早速ASP.NET AJAXを使ってみましょう。ここでは、前回、前々回と同様、ゆうパックの料金を調べるWebアプリケーションを作成します。
Visual Studioを使用した場合の手順は、次のようになります。
- メニューの[ファイル]-[新規作成]-[Webサイト]から、「ASP.NET AJAX-Enabled Web Site」テンプレートを使用して、新しいWebサイトを作成します。(「ASP.NET AJAX-Enabled Web Site」テンプレートを使わなかった場合は、Web.configを適当に書き換えてください。)
- Default.aspxのデザインを開きます。ScriptManagerコントロールが一つ配置されていることを確認します。新しいページを作成したなどでScriptManagerが配置されていない場合は、ツールボックスの「AJAX Extensions」タブからScriptManagerをページにドラッグ&ドロップして、配置します。ScriptManagerは必ず1つのページに1つだけ配置します。
- ツールボックスの「AJAX Extensions」タブからUpdatePanelをページにドラッグ&ドロップして、配置します。
- 前々号の「Ajaxを使用しない方法」で紹介したのと全く同じ方法でコントロールの配置と設定をし、さらに、全く同じコードを記述します。ただしコントロールは、すべてUpdatePanelコントロール内に配置します。具体的なコードは、次のようになります(ここでは、単一ページにしています)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
| | <%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub PackageSizeList_SelectedIndexChanged( _
ByVal sender As Object, ByVal e As EventArgs)
Dim ddl As DropDownList = CType(sender, DropDownList)
If ddl.SelectedValue <> "0" Then
Dim fee As Integer = _
Me.GetYoupackFee(Integer.Parse(ddl.SelectedValue))
ResultLabel.Text = String.Format("料金は {0}円", fee)
Else
ResultLabel.Text = ""
End If
End Sub
Public Function GetYoupackFee(ByVal packSize As Integer) As Integer
If packSize <= 60 Then
Return 600
ElseIf packSize <= 80 Then
Return 800
ElseIf packSize <= 100 Then
Return 1000
ElseIf packSize <= 120 Then
Return 1200
ElseIf packSize <= 140 Then
Return 1400
ElseIf packSize <= 160 Then
Return 1600
ElseIf packSize <= 170 Then
Return 1700
Else
Return -1
End If
End Function
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>ゆうパック送料検索</title>
</head>
<body>
<h1>ゆうパック送料検索</h1>
<p>同一都道府県内への配達、重量30kgまで</p>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label
ID="Label1"
runat="server"
Text="荷物の大きさ(縦・横・高さの合計): "
AssociatedControlID="PackageSizeList">
</asp:Label>
<asp:DropDownList
ID="PackageSizeList"
runat="server"
AutoPostBack="True"
OnSelectedIndexChanged="PackageSizeList_SelectedIndexChanged">
<asp:ListItem Value="0">(選択してください)</asp:ListItem>
<asp:ListItem Value="60">60cmまで</asp:ListItem>
<asp:ListItem Value="80">80cmまで</asp:ListItem>
<asp:ListItem Value="100">100cmまで</asp:ListItem>
<asp:ListItem Value="120">120cmまで</asp:ListItem>
<asp:ListItem Value="140">140cmまで</asp:ListItem>
<asp:ListItem Value="160">160cmまで</asp:ListItem>
<asp:ListItem Value="170">170cmまで</asp:ListItem>
</asp:DropDownList>
<br />
<asp:Label ID="ResultLabel" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
| | <%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void PackageSizeList_SelectedIndexChanged(
object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
if (ddl.SelectedValue != "0")
{
int fee = this.GetYoupackFee(int.Parse(ddl.SelectedValue));
ResultLabel.Text = string.Format("料金は {0}円", fee);
}
else
{
ResultLabel.Text = "";
}
}
public int GetYoupackFee(int packSize)
{
if (packSize <= 60)
return 600;
else if (packSize <= 80)
return 800;
else if (packSize <= 100)
return 1000;
else if (packSize <= 120)
return 1200;
else if (packSize <= 140)
return 1400;
else if (packSize <= 160)
return 1600;
else if (packSize <= 170)
return 1700;
else
return -1;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>ゆうパック送料検索</title>
</head>
<body>
<h1>ゆうパック送料検索</h1>
<p>同一都道府県内への配達、重量30kgまで</p>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label
ID="Label1"
runat="server"
Text="荷物の大きさ(縦・横・高さの合計): "
AssociatedControlID="PackageSizeList">
</asp:Label>
<asp:DropDownList
ID="PackageSizeList"
runat="server"
AutoPostBack="True"
OnSelectedIndexChanged="PackageSizeList_SelectedIndexChanged">
<asp:ListItem Value="0">(選択してください)</asp:ListItem>
<asp:ListItem Value="60">60cmまで</asp:ListItem>
<asp:ListItem Value="80">80cmまで</asp:ListItem>
<asp:ListItem Value="100">100cmまで</asp:ListItem>
<asp:ListItem Value="120">120cmまで</asp:ListItem>
<asp:ListItem Value="140">140cmまで</asp:ListItem>
<asp:ListItem Value="160">160cmまで</asp:ListItem>
<asp:ListItem Value="170">170cmまで</asp:ListItem>
</asp:DropDownList>
<br />
<asp:Label ID="ResultLabel" runat="server"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
|
以上ですべて終了です。
驚くことに、前々回紹介した、Ajaxを使用せずに、今までどおりポストバックを使用する方法と、ほとんど同じになります。コードは全く同じで、違いは、荷物のサイズを選択するDropDownListコントロールと、結果を表示するLabelコントロールがUpdatePanelコントロールの中(<ContentTemplate>の中)に入っていることだけです。自分でJavaScriptを書く必要も、Webサービスを作成する必要もありません。
UpdatePanelコントロールを使うためには、ScriptManagerコントロールが必要です。もしUpdatePanelコントロールを使いたいページにScriptManagerコントロールが無ければ、まずScriptManagerコントロールを追加してから、UpdatePanelコントロールを追加します。ScriptManagerコントロールは、1つのページに1つだけ配置できます。
補足:UpdatePanelコントロールの部分に出力されるHTMLは、<div>で囲まれた状態になります。
トリガーをUpdatePanelの外に出す †
上記の例では全てのコントロールをUpdatePanelコントロール内に入れていましたが、基本的には、変化のある部分だけをUpdatePanelコントロール内に入れた方が良いです。変化のない部分をUpdatePanelコントロール内に入れてしまうと、サーバーは変化のない部分も含めた更新後のHTMLを送信するため、無駄が多くなり、効率的でありません。
UpdatePanelコントロールの中身を更新するためのきっかけとなるコントロール(トリガー)をUpdatePanelの外に出したときは、UpdatePanelのTriggersプロパティにトリガーの情報を追加する必要があります。
実際に上記のコードを改造してみましょう。
- "Label1"と"PackageSizeList"をUpdatePanelの外に出します。
- デザイナで"UpdatePanel1"を選択し、プロパティウィンドウの"Triggers"の右にある「...」ボタンをクリックして、「UpdatePanelTriggerコレクションエディタ」を表示します。
- 「追加」ボタンをクリックして、「メンバ」に「AsyncPostBack」を追加します。
- 「ControlID」プロパティを"PackageSizeList"とします。つまり、このUpdatePanelを更新するトリガーとなるコントロールに"PackageSizeList"ドロップダウンリストを指定します。
- 「EventName」プロパティを"SelectedIndexChanged"とします。つまり、SelectedIndexChangedイベントが発生した時にUpdatePanelが更新されるようにします。(この場合は、何も指定しなくても大丈夫です。)
- 「OK」ボタンをクリックします。
- 以上です。
この改造によって出来上がったコードは、次のようになります。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
| | <%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub PackageSizeList_SelectedIndexChanged( _
ByVal sender As Object, ByVal e As EventArgs)
Dim ddl As DropDownList = CType(sender, DropDownList)
If ddl.SelectedValue <> "0" Then
Dim fee As Integer = _
Me.GetYoupackFee(Integer.Parse(ddl.SelectedValue))
ResultLabel.Text = String.Format("料金は {0}円", fee)
Else
ResultLabel.Text = ""
End If
End Sub
Public Function GetYoupackFee(ByVal packSize As Integer) As Integer
If packSize <= 60 Then
Return 600
ElseIf packSize <= 80 Then
Return 800
ElseIf packSize <= 100 Then
Return 1000
ElseIf packSize <= 120 Then
Return 1200
ElseIf packSize <= 140 Then
Return 1400
ElseIf packSize <= 160 Then
Return 1600
ElseIf packSize <= 170 Then
Return 1700
Else
Return -1
End If
End Function
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>ゆうパック送料検索</title>
</head>
<body>
<h1>ゆうパック送料検索</h1>
<p>同一都道府県内への配達、重量30kgまで</p>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Label
ID="Label1"
runat="server"
Text="荷物の大きさ(縦・横・高さの合計): "
AssociatedControlID="PackageSizeList">
</asp:Label>
<asp:DropDownList
ID="PackageSizeList"
runat="server"
AutoPostBack="True"
OnSelectedIndexChanged="PackageSizeList_SelectedIndexChanged">
<asp:ListItem Value="0">(選択してください)</asp:ListItem>
<asp:ListItem Value="60">60cmまで</asp:ListItem>
<asp:ListItem Value="80">80cmまで</asp:ListItem>
<asp:ListItem Value="100">100cmまで</asp:ListItem>
<asp:ListItem Value="120">120cmまで</asp:ListItem>
<asp:ListItem Value="140">140cmまで</asp:ListItem>
<asp:ListItem Value="160">160cmまで</asp:ListItem>
<asp:ListItem Value="170">170cmまで</asp:ListItem>
</asp:DropDownList>
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="ResultLabel" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="PackageSizeList"
EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
| | <%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void PackageSizeList_SelectedIndexChanged(
object sender, EventArgs e)
{
DropDownList ddl = (DropDownList)sender;
if (ddl.SelectedValue != "0")
{
int fee = this.GetYoupackFee(int.Parse(ddl.SelectedValue));
ResultLabel.Text = string.Format("料金は {0}円", fee);
}
else
{
ResultLabel.Text = "";
}
}
public int GetYoupackFee(int packSize)
{
if (packSize <= 60)
return 600;
else if (packSize <= 80)
return 800;
else if (packSize <= 100)
return 1000;
else if (packSize <= 120)
return 1200;
else if (packSize <= 140)
return 1400;
else if (packSize <= 160)
return 1600;
else if (packSize <= 170)
return 1700;
else
return -1;
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>ゆうパック送料検索</title>
</head>
<body>
<h1>ゆうパック送料検索</h1>
<p>同一都道府県内への配達、重量30kgまで</p>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:Label
ID="Label1"
runat="server"
Text="荷物の大きさ(縦・横・高さの合計): "
AssociatedControlID="PackageSizeList">
</asp:Label>
<asp:DropDownList
ID="PackageSizeList"
runat="server"
AutoPostBack="True"
OnSelectedIndexChanged="PackageSizeList_SelectedIndexChanged">
<asp:ListItem Value="0">(選択してください)</asp:ListItem>
<asp:ListItem Value="60">60cmまで</asp:ListItem>
<asp:ListItem Value="80">80cmまで</asp:ListItem>
<asp:ListItem Value="100">100cmまで</asp:ListItem>
<asp:ListItem Value="120">120cmまで</asp:ListItem>
<asp:ListItem Value="140">140cmまで</asp:ListItem>
<asp:ListItem Value="160">160cmまで</asp:ListItem>
<asp:ListItem Value="170">170cmまで</asp:ListItem>
</asp:DropDownList>
<br />
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="ResultLabel" runat="server"></asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="PackageSizeList"
EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
|
UpdatePanelの制限 †
このようにUpdatePanelは非常に簡単で、便利ですが、注意しなければならない点も多々あります。
例えば、UpdatePanelの中に入れることのできないコントロールもあります。TreeView、Menu、WebParts、SubstitutionコントロールはUpdatePanelの中に入れて使うことができません。FileUpload、GridView、DetailsView、Login、PasswordRecovery、ChangePassword、CreateUserWizard、検証(Validation)コントロールは、制限付きでUpdatePanelの中に入れて使うことができます。詳しくは、「UpdatePanel Control Overview」をご覧ください。
今回はこれでおしまいです。次回もASP.NET AJAXについて説明します。
参考 †
コメント †