読者です 読者をやめる 読者になる 読者になる

AjaxControlToolKitを利用した際のHttpException(コードブロック例外)を回避する

ASP.NET

AjaxControlToolkitを利用したWeb Formsアプリケーションで、headタグにコードブロックを使用している場合に以下のような例外が発生する場合があります。

System.Web.HttpException (0x80004005): コントロールにコード ブロック (<% ... %>) が含まれているため、コントロールのコレクションを変更できません。
   場所 System.Web.UI.ControlCollection.Add(Control child)
   場所 AjaxControlToolkit.ScriptObjectBuilder.RegisterCssReferences(Control control)
   場所 AjaxControlToolkit.ExtenderControlBase.OnLoad(EventArgs e)
   場所 AjaxControlToolkit.HtmlEditorExtender.OnLoad(EventArgs e)
   場所 System.Web.UI.Control.LoadRecursive()
   場所 System.Web.UI.Control.LoadRecursive()
   場所 System.Web.UI.Control.LoadRecursive()
   場所 System.Web.UI.Control.LoadRecursive()
   場所 System.Web.UI.Control.LoadRecursive()
   場所 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

環境

ASP.NET Web Forms

原因

これはAjaxControlToolKitの仕様によるものです。 世の中の皆様も多少悩まれております。
visual studio 2008 - Trying to add ajax TabContainer, getting error "The Controls collection cannot be modified because the control contains code blocks (i.e. <% ... %>)." - Stack Overflow

なお少し前にリリースされたv15.1でも変わらず発生します。

community.devexpress.com

回避方法

コードブロックでなければいいので、スタイルシートをバインドしたい場合等は[<%# ~ %>]に修正することで回避できます。
インライン式については以下参照ください。
.NET Framework の ASP.NET インライン数式の概要

では条件分岐してスタイル変えたいような場合どうしたらいいのか?これ単純です。

  • headタグをサーバコントロール化し、
<head id="head" runat="server">
  • コードビハインドで処理した結果をheaderコントロールに追加します。
HtmlLink link = new HtmlLink();       
link.Attributes.Add("rel", "stylesheet");
link.Attributes.Add("type", "text/css");
link.Href = "~/hogehoge.css";
Page.Header.Controls.Add(link);

AjaxControlToolkit / Web Formsを利用する機会自体減っているかと思いますが、頭の片隅にとどめておくといいかもしれません。