Problem
When working with MasterPages, a common irritation I run into is that script tags in the master are relative to the consuming page.
So for instance, your JavaScript might work if your consuming page is in the root of your app, but when you put another page in a subfolder, the relative path breaks and the JavaScript is not found. And there isn't a way to use absolute paths that I'm aware of in this case.
This last time, I decided to really attack this and find a good solution.
Proposed Solutions
I tried one strategy that revolved around calling ClientScriptManager.RegisterClientScriptInclude in Page_Load, but that didn't seem to render anything (granted, my understanding of the related plumbing is incomplete).
I tried another one that looked something like this:
<script language="javascript" src='<%= ResolveClientUrl("~/js/ddnmenu.js") %>' type="text/javascript"></script>
...But that throws an exception: The Controls collection cannot be modified because the control contains code blocks.
Working (but somewhat fugly) Code
So, what I ended up going with is a Literal control in the Head where I render the appropriate Html:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.SetupLiteralScriptsTag()
End Sub
Private Sub SetupLiteralScriptsTag()
'Build the script tags to import our JavaScript
Dim Builder As New StringBuilder
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery-1.3.2.min.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/jquery.corners.min.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/bg.pos.js")))
Builder.AppendLine(String.Format("<script type=""text/javascript"" src=""{0}""""></script>", ResolveClientUrl("~/js/moonstone.js")))
Me.LiteralScriptTags.Text = Builder.ToString
End Sub
This works, but I'm not on fire about it since it seems like a bit too much of a workaround for what must be an extremely common problem. Is there a better way?