Добавить скрипт сервера ASP.NET в в основном статические файлы .JS / .CSS без потери IntelliSense?

Используя VS2008 и ASP.NET 3.5 (или VS 2010 / .NET 4.0?), Как я могу включить немного динамического серверного кода ASP.NET в в основном статические файлы JavaScript и CSS?

Я хочу сделать это, чтобы избежать клонирования целых файлов JS или CSS для изменения лишь небольшой части из мультитенантных сайтов. Позже я хочу расширить решение для обработки локализации внутри javascript / CSS, поддержки динамической отладки / трассировки и других интересных вещей, которые вы можете получить, динамически вводя данные в JavaScript и CSS.

Сложность в том, что я не хочу терять все крутые вещи, которые вы получаете со статическими файлами, например:

  • Раскраска кода JS / CSS и intellisense
  • Поддержка CSS-класса "перейти к определению" в IDE
  • автоматические заголовки кэширования HTTP на основе даты базового файла
  • автоматическое сжатие IIS

Качество статических файлов на стороне сервера (например, заголовки / сжатие) можно подделать с помощью HttpHandler, но сохранение качества IDE (intellisense / color / etc) поставило меня в тупик.

Идеальное решение отвечало бы следующим требованиям:

  1. VS IDE обеспечивает интеллект JS / CSS и раскраску кода. Отказаться от intellisense с серверным кодом - это нормально, поскольку серверный код обычно прост в этих файлах.
  2. "перейти к определению" по-прежнему работает для классов CSS (как и в статических файлах CSS)
  3. отправлять заголовки кэширования HTTP, которые зависят от даты изменения базового файла.
  4. поддержка сжатия HTTP, как и другие статические файлы
  5. поддержка ‹% =%› и ‹script runat = server› блоки кода
  6. Пути URL (по крайней мере те, которые видят HTTP-клиенты) заканчиваются на .JS или .CSS (не .ASPX). При желании я могу использовать строку запроса или PathInfo для параметризации (например, выбора языкового стандарта), хотя в большинстве случаев я буду использовать для этого vdirs. Кеширование должно отличаться для разных строк запроса.

Пока что лучшее (хакерское) решение, которое я придумал, таково:

  • Переключите базовые файлы CSS или JS на файлы .ASPX (например, foo.css.aspx или foo.js.aspx). Встраивайте базовое статическое содержимое в элемент STYLE (для CSS) или элемент SCRIPT (для JS). Это позволяет использовать intellisense JS / CSS, а также разрешать встроенные блоки кода или блоки кода runat = server.
  • Write an HttpHandler which:
    • looks at the URL and adds .aspx to know the right underlying ASPX to call
    • использует System.Net.HttpWebRequest для вызова этого URL
    • удаляет содержащиеся теги STYLE или SCRIPT, оставляя только CSS или JS
    • добавляет соответствующие заголовки (кеширование, тип содержимого и т. д.)
    • сжимает ответ, если клиент поддерживает сжатие
  • Сопоставьте * .CSS и * .JS моему обработчику.
  • (если IIS6) Убедитесь, что расширения файлов .JS и .CSS сопоставлены с ASP.NET.

Я уже использую модифицированную версию HttpCompression Module Darick_c, которая обрабатывает почти все из выше для меня, поэтому изменить его для поддержки решения выше не будет слишком сложно.

Но мое решение взломано. Мне было интересно, есть ли у кого-нибудь более легкий подход к этой проблеме, который не теряет достоинства статических файлов Visual Studio.

Я знаю, что могу также взломать решение только на стороне клиента, в котором я разделю все JS и CSS на файлы «разные» и «не будут меняться», но для такого решения есть накладные расходы на производительность и обслуживание, которые я бы хотелось бы избежать. Мне действительно нужно решение на стороне сервера, чтобы я мог поддерживать на сервере один файл, а не N + 1 файлы.

Я еще не пробовал VS10 / .NET 4.0, но я открыт для решения Dev10 / .net4, если это лучший способ заставить этот сценарий работать.

Спасибо!


person Justin Grant    schedule 07.08.2009    source источник
comment
Я думаю, вы неправильно смотрите на проблему. Что касается javascript, я думаю, вы должны спросить себя, как параметризовать javascript, который у вас есть, чтобы можно было передать содержимое ASP.NET (или ссылку на него). Я не понимаю, почему вам нужен ASP.NET разметка в файле CSS вообще.   -  person Frank Schwieterman    schedule 31.10.2009
comment
Вы правы в том, что включение сценария сервера ASP.NET - это лишь один из способов изменения / параметризации содержимого CSS или JS. Я открыт и для других подходов - я просто предположил (возможно, ошибочно), что включение блоков ‹% =%› было бы наиболее естественным. Для CSS существует множество причин для динамического изменения содержимого CSS, включая локализацию фонов изображений, тематику цветов и т. Д. Этого можно достичь, разделив файлы CSS на одинаковые и разные части и объединяя их во время выполнения, но это может быть трудным в обслуживании по сравнению с простой возможностью вводить различные части через код во время выполнения.   -  person Justin Grant    schedule 03.11.2009
comment
Для файлов CSS вам, вероятно, лучше сохранить отдельные файлы CSS для каждого языка или темы, которые вы хотите использовать, а затем использовать код на стороне сервера для создания тега ‹link›, связывающегося с правильным файлом CSS.   -  person Shawn Steward    schedule 06.11.2009
comment
@Shawn Steward - если каждый язык или тема определяет взаимоисключающий CSS, тогда ваш подход имеет смысл, но если (как в моем случае) есть только небольшое количество различных CSS, а все остальное идентично, я не хочу добавлять perf для другого HTTP-запроса и проблема управления кодом для большого количества новых файлов, чтобы иметь дело с введением 2-3 строк отклонения в большой файл CSS.   -  person Justin Grant    schedule 06.11.2009


Ответы (2)


Я решил аналогичную проблему, заставив главную страницу выводить динамически сгенерированный объект JSON в нижнем колонтитуле каждой страницы.

Мне нужно, чтобы диалоговое окно входа в систему js всплывающее окно поддерживало локализацию. Поэтому, используя JSON.NET для сериализации, я создал свойство коллекции открытого ключа / значения главной страницы, к которому страницы могли получить доступ, чтобы размещать ключи / значения, например, в пары ключ-фраза / локализованная фраза. Затем главная страница отображает динамический объект JSON, содержащий эти значения, чтобы статические файлы js могли ссылаться на эти динамические значения.

Для окна входа в систему js у меня на главной странице установлены локализованные значения. Это имело смысл, потому что главная страница также включает файл login.js.

person Tim Santeford    schedule 06.11.2009
comment
Другими словами, вы сохранили статический JS, но на странице предварительно была заполнена глобальная переменная, которую впоследствии повторно использовал статический файл JS? Это кажется хорошим решением для JS, хотя оно делает JS несамостоятельным, что может немного усложнить повторное использование и тестирование. Я предполагаю, что могу применить тот же подход к моему CSS, внедрив динамически сгенерированный элемент STYLE на мою главную страницу, который переопределяет стили CSS, установленные в моем основном файле. - person Justin Grant; 06.11.2009
comment
Чтобы статический файл js был самодостаточным, дайте файлу js определить глобальный массив и заполнить его значениями по умолчанию. Затем разрешите главной странице при необходимости перезаписать значения по умолчанию. - person Tim Santeford; 06.11.2009
comment
О внедрении CSS. Если количество CSS, которое отличается только на одну или две строки, я думаю, что введение короткого переопределения на главную страницу вполне приемлемо. - person Tim Santeford; 06.11.2009
comment
Привет, Тим - это кажется лучшим подходом, который я видел до сих пор, и не совсем хакерским, что приятно. Ответ Брайана аналогичен и содержит более подробную информацию, но ваш пришел первым и имеет, IMHO, более надежное решение javascript, так что вы получите бой. Спасибо за вашу помощь! - person Justin Grant; 07.11.2009

Я хочу поблагодарить вас за беспокойство по поводу количества HTTP-запросов, сделанных от клиента, и возвращаемых полезных данных. Слишком много людей, которых я знаю и с которыми я работаю, не замечают этих простых оптимизаций. Однако всякий раз, когда я сталкиваюсь с той же проблемой, с которой вы сталкиваетесь (что на самом деле случается довольно часто), я обнаруживал, что обычно либо где-то ошибаюсь, либо пытаюсь решить проблему неверным способом.

Что касается вашего вопроса JS, я думаю, что Фрэнк Швитерман в комментариях выше прав. Я бы искал способы раскрыть динамические части вашего JS через сеттеры. Очень простой пример - если вы хотите отображать настраиваемое приветственное сообщение для пользователей при входе в систему. В вашем JS-файле вы можете указать метод setMessage (message). Затем этот метод будет вызываться страницей, содержащей сценарий. В результате у вас будет что-то вроде:

<body onLoad="setMessage('Welcome' + <%= user.FirstName %>);">

Очевидно, это можно расширить, передав объекты или методы в статический файл JS, чтобы предоставить вам желаемую функциональность.

Отвечая на вопрос CSS, я думаю, что вы можете многое извлечь из подхода, который Шон Стюард из комментариев делает хорошо. Вы можете определить определенные статические части вашего CSS в базовом файле, а затем переопределить части, которые вы хотите изменить в других файлах. В результате вы можете диктовать внешний вид своего веб-сайта с помощью того, какие файлы вы включаете. Кроме того, поскольку вы не хотите получать дополнительные HTTP-запросы (имейте в виду, если вы настроили кэширование этих файлов на неделю, месяц и т. Д., Это одноразовый запрос), вы можете сделать что-то вроде объединения файлы CSS в один файл во время компиляции или выполнения.

Что-то вроде следующих ссылок может помочь вам указать правильное направление:

http://geekswithblogs.net/rashid/archive/2007/07/25/Combine-Multiple-JavaScript-and-CSS-Files-and-Remove-Overheads.aspx

http://www.asp.net/learn/3.5-SP1/video-296.aspx?wwwaspnetrdirset=1

http://dimebrain.com/2008/04/resourceful-asp.html

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

person Brian Hasden    schedule 06.11.2009
comment
Привет, Брайан, это отличная информация, спасибо. Я уже комбинирую свои файлы CSS и JS (используя модифицированную версию модуля Darick_c HttpCompression), поэтому ваше решение прекрасно сочетается с тем, что я уже использую. Я признаю, что не являюсь поклонником вашего подхода к установке JS, потому что он требует более защитного кодирования в тех случаях, когда внешний скрипт не загружается (например, проблемы с сетью, странные проблемы с синхронизацией и т. Д.). JS-решение Тима по установке глобальных переменных на главной странице и использованию сценария для извлечения этих переменных кажется более безопасным. Но ваше решение - хорошее, и оно заслуживает +1! Спасибо еще раз за помощь. - person Justin Grant; 07.11.2009
comment
Без проблем. Какие изменения вы внесли в модуль сжатия? Я использую набор инструментов ajax ToolkitScriptManager для объединения моих скриптов, но я использую его только для JS и в настоящее время не использую ничего для сжатия или файлов CSS. - person Brian Hasden; 08.11.2009