佐々木屋

技術的なことから趣味まで色々書きます

src属性のルート相対パス設定あれこれ

ASP.NETなどのHTMLでJavascriptや画像などの場所をsrc属性で指定する場合、普通のコンテンツページの場合は問題ありませんが、マスターページを利用していてそのコンテンツが異なる階層の場合、固定的に相対パスを記述すると読み込めなくなります。

例えば以下のような階層で作成した場合です。

WebForm1とWebForm2はどちらもSite1マスターページのコンテンツページです。
マスターページ側でJavascriptを読むように記述した場合、ScriptsフォルダはWebForm1から見た場合一つ上ですが、WebForm2から見た場合は二つ上になります。

このような場合はチルダを使ったルート相対パスを利用しますが、href属性と異なり、src属性はチルダを使っても勝手にルート相対パスへ変換してくれません。src属性を使ったチルダはResolveClientUrlメソッドを使ってインライン式(<%=・・・%>)を埋め込むことで変換されます。

<script src="<%= this.ResolveClientUrl("~/scripts/javascript.js") %>" type="text/javascript"></script>

※headタグ内に記載する場合はheadタグにrunat="server"を追加して下さい


大抵の場合はこれで解決するはずですが、クライアント側に記載したタグ内部に対してサーバー側イベント(C#側のPage_InitやPage_Loadなど)で変更を加えるような処理を行うと、「コントロールにコード ブロック (<% ... %>) が含まれているため、コントロールのコレクションを変更できません。」のエラーが発生してしまいます。


これを回避するにはいくつか手法があります(全てサーバー側で記述する、全てインライン式で記述する等)が、一番楽な方法は以下のように必要なインライン式部分をPlaceHolderタグで囲む方法です。

<asp:PlaceHolder ID="plhJS" runat="server">
   <script src="<%= this.ResolveClientUrl("~/scripts/javascript.js") %>" type="text/javascript"></script>
</asp:PlaceHolder>


これでWebForm1からだと「../scripts/javascript.js」、WebForm2だと「../../scripts/javascript.js」で変換してくれます。