WebForms: динамические (или абсолютные) теги сценариев в MasterPages

Проблема

При работе с мастер-страницами меня обычно раздражает то, что теги сценария в мастер-странице относятся к странице-потребителю.

Так, например, ваш JavaScript может работать, если ваша потребляющая страница находится в корневом каталоге вашего приложения, но когда вы помещаете другую страницу во вложенную папку, относительный путь разрывается и JavaScript не найден. И в этом случае нет способа использовать абсолютные пути, о которых я знаю.

В последний раз я решил по-настоящему атаковать это и найти хорошее решение.

Предлагаемые решения

Я попробовал одну стратегию, которая вращалась вокруг вызова ClientScriptManager.RegisterClientScriptInclude в Page_Load, но, похоже, ничего не отображалось (конечно, мое понимание связанной сантехники неполное).

Я попробовал еще один, который выглядел примерно так:

<script language="javascript" src='<%= ResolveClientUrl("~/js/ddnmenu.js") %>' type="text/javascript"></script>

... Но возникает исключение: коллекцию Controls нельзя изменить, поскольку элемент управления содержит блоки кода.

Рабочий (но несколько неуклюжий) код

Итак, в итоге у меня появился элемент управления Literal в голове, где я визуализирую соответствующий 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

Это работает, но я не в восторге от этого, так как это кажется слишком большим обходным путем для того, что должно быть чрезвычайно распространенной проблемой. Есть ли способ лучше?


person Brian MacKay    schedule 30.06.2009    source источник


Ответы (5)


Я везде использую относительный синтаксис приложения. У него есть недостаток: если вы измените имя/путь приложения, у вас будет много работы по обновлению всех ваших URL-адресов.

‹script language="javascript" src="/MyAppName/Includes/MyJavascriptFile.js">

или если вы работали над корневым приложением, то:

‹script language="javascript" src="/Includes/MyJavascriptFile.js">

person Paul Prewett    schedule 30.06.2009
comment
По крайней мере, работа сведена к минимуму в сценарии мастер-страниц. Удивительно, что я не знал, что так можно сделать... Я очень давно работаю над веб-приложениями! - person Brian MacKay; 30.06.2009
comment
Я принял этот ответ вместо ответа M4N, так как он самый простой. Вы можете использовать его, не вводя никаких новых концепций в свой проект... Хотя сейчас я использую для этого ScriptManager. - person Brian MacKay; 02.11.2012

Вы можете добавить менеджер сценариев на главную страницу и включить через него файлы javascript:

<asp:ScriptManager ...>
  <Scripts>
    <asp:ScriptReference Path="~/js/ddnmenu.js" />
  </Scripts>
</asp:ScriptManager>

Еще одним преимуществом такого подхода является то, что вы можете затем добавить элемент управления ScriptManagerProxy на свои страницы содержимого (и пользовательские элементы управления), чтобы включить любые дополнительные сценарии.

Некоторые сторонние замены для ASP:ScriptManager (например, из пакета RadControls telerik или из пакета инструментарий управления Ajax) предлагает еще больше возможностей, таких как объединение всех включенных файлов сценариев Java в один файл (таким образом уменьшая количество необходимых HTTP-запросов). для загрузки страницы).

Редактировать: использование ScriptManager имеет некоторые другие преимущества, например. вы можете отправлять отладочные или выпускные версии своих сценариев в браузер или сценарии, зависящие от региональных параметров, и т. д. и т. д. Посмотрите эту страницу в MSDN для обзора.

person M4N    schedule 30.06.2009
comment
Тогда просто примите мой ;-) - нет, серьезно, примите тот ответ, который вам больше всего помог. - person M4N; 15.07.2009

Я использую Page.resolveUrl("~/somefile.js");

работает как чемпион

person smercer    schedule 30.06.2009

Вы всегда можете ссылаться на свой скрипт из корня. IE:

<script language="javascript" src="/scripts/file.js"></script>

Любая страница в вашем приложении будет правильно получать javascript.

Кроме того, поскольку вы работаете с ASP.NET, вы можете использовать символ «~» для предоставления относительных путей на основе приложений. См. статью Рика Страла о путях ASP.NET для получения дополнительной информации.

person nikmd23    schedule 30.06.2009
comment
Тильда работает только внутри элементов управления сервером. Хотя я хотел бы использовать его здесь. - person Brian MacKay; 30.06.2009

Коллекция Controls не может быть изменена, так как элемент управления содержит блоки кода.

Эта ошибка звучит знакомо. Эта страница помогла, когда я пробирался через эту

person Dan F    schedule 30.06.2009