by WebSurfer
2010年11月5日 21:04
AJAX Control Toolkit の TabContainer や Calendar を使用する際、head 要素内にコードブロック(即ち、<% ... %>)を定義すると例外がスローされるという問題と回避策の紹介です。なお、この問題は .NET 4 でも同様に発生します。
Calendar や TabContainer は AjaxControlToolkit.ScriptObjectBuilder クラスの RegisterCssReferences メソッドを起動し、head タグ内に HTML link 要素(CSS ファイルの定義)を追加しようとします。その時に head タグ内にコードブロックがあると、画像に示したように例外をスローします。
この問題を再現する具体的なコード例を下に載せておきます。この例のように JavaScript を定義する際に ClientID を取得するため、コードブロックを埋め込むケースはよくあるのではないでしょうか。
回避策は書くまでもないですが、コードブロックを head タグの外に移動するだけです。
なお、'<%=TextBox1.ClientID%>' の代わりに、実際の ClientID をプログラマがハードコーディングするのは避けたほうがよさそうです。何故なら、コントロールを配置する場所によって Client ID は変化しますし、コードを変更しなくても将来の ASP.NET の仕様の変更で変わるかもしれませんので。
<%@ Page Language="C#" %>
<%@ Register Assembly="AjaxControlToolkit"
Namespace="AjaxControlToolkit"
TagPrefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<script type="text/javascript">
<!--
function ShowText() {
var txtbx = $get('<%=TextBox1.ClientID%>');
txtbx.value = 'これはテストです。';
}
//-->
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ToolkitScriptManager ID="ToolkitScriptManager1"
runat="server">
</asp:ToolkitScriptManager>
<asp:TextBox ID="TextBox1"
runat="server"
Text="Test" />
<asp:Button ID="Button1"
runat="server"
Text="Button"
OnClientClick="ShowText(); return false;" />
<asp:TabContainer ID="TabContainer1"
runat="server"
ActiveTabIndex="0"
Height="160px"
Width="360px">
<asp:TabPanel runat="server"
HeaderText="TabPanel1"
ID="TabPanel1">
<ContentTemplate>ABCDE</ContentTemplate>
</asp:TabPanel>
<asp:TabPanel ID="TabPanel2"
runat="server"
HeaderText="TabPanel2">
<ContentTemplate>FGHIJ</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
</div>
</form>
</body>
</html>