Мои профессиональные обязанности связаны с разработкой CMS на ASP.Net. У нас уже сейчас более десятка клиентов, и все они время от времени хотят получать обновления :). Жестких релизов и «цикла поддержки» у нас нет, поэтому у каждого клиента может оказаться фактически произвольная версия.
Особенность такого цикла разработки всплывает в тех случаях, когда у клиента, последнее обновление которого было месяца 3-4 назад всплывает мелкий баг и клиент очень хочет его пофиксить. Однако обновиться до последней версии часто непросто, потому что система развивается очень быстро, и полноценное обновление скорее всего потребует комплексное обновление БД и 1С, что может быть довольно дорого по времени/усилиям/деньгам :)
Выход из этой ситуации довольно прост — при деплое сайта на каждого клиента необходимо создавать ветку, из которой при необходимости и проводить «горячие фиксы» клиента.
Здесь всплывает и чисто человеческий фактор, что «забыть» сделать ветку при деплое в спешке очень и очень легко, особенно если таких деплоев за день несколько :)
Дабы не страдать от подобной забывчивости я и решил автоматизировать процесс создания веток, а заодно и ознакомиться с возможностями расширения Visual Studio.
Continue reading
T4MVCJS отрефакторен и выложен на codeplex
Недавно дошли руки до выкладывания T4MVCJS в opensource. Распространение исходников в зип-архиве показалось слегка устаревшей методикой и мы переехали на codeplex :)
Попутно было слегка отрефакторено использование T4MVC, вместо простой «копипасты» теперь используется оригинальный исходник с вырезанными из него строками, отвечающими за генерацию T4MVC-хэлперов. Таким образом легко и просто используется весь парсинг, осуществляемый T4MVC, и обновление до новых версий будет представлять куда меньше проблем (скопипастить файл, выкинуть 400 подряд идущих строк — вуа-ля :)).
Помимо эстетического удовлетворения это позволило с лёгкостью обрабатывать MVC Area (предыдущая версия, этого не умела, за репорт этого бага спасибо Брайану Бетти).
Заодно я задумался о проблеме существования двух экшенов с одинаковыми именами — в Javascript перегрузка функций, к сожалению, недоступна. В результате на свет появляются экшены Edit, Edit1, Edit2, etc. :) Если кто-нибудь предложит более адекватное решение проблемы — я бы с удовольствием его обсудил :)
P.S. в качестве системы контроля версий T4MVCJS используется Mercurial, так что при желании внести изменения — форкайте с удовольствием :)
P.P.S. На момент изначальной публикации поста ареи-таки не работали. Начиная с версии 1.0.10 всё ок.
T4MvcJs — строготипизированный яваскрипт-хелпер для URL
Не так давно я уже писал о решении проблемы «магических строк» в яваскрипте, примером таких строк могут служить url экшенов («/Home/Index?name=John&lastname=Doe»)
В разор-вьюшках проблему написания урлов «напрямую» можно решить с помощью T4Mvc: @Url.Action(MVC.Actions.Home.Index(«John», «Doe)). Проблема в том, что этот код — серверный, и написать что-то подобное в script.js — не получится.
В предыдущем посте я уже предлагал решение проблемы, однако(об этом я также писал) в нём была существенная недоработка. Новая версия T4MvcJs эти недоработки устраняет, и в результате мы, как и прежде, спокойно сможем писать в яваскрипт файлах что-то вроде: MvcActions.Home.Index(«John», «Doe»), и это будет полностью клиентский код.
Continue reading
Nuget пакет для JsValidator’a
Наконец-то создан nuget-пакет для JsValidator‘a, о котором я не так давно писал.
Теперь интеграция проверки яваскрипта в любой проект займет минимум времени: Install-Package JsValidator в nuget-консоли — это всё, что нужно. Название пакета, как нетрудно догадаться — JsValidator.
Пакет делает всё то, что раньше приходилось делать руками: скачивает бинарники валидатора, создает тестовый конфиг, прописывает себя в post-build-events.
При удалении пакета всё, где пакет наследил, аккуратненько удаляется.
По факту окончания разработки JsValidator’a написан анонс проекта на Хабрахабре. Желающие приглашаются к обсуждению в любом из источников :)
Валидация JavaScript в ASP.Net MVC проекте — еще один велосипед или jsvalidator.codeplex.com
В предыдущей заметке я рассматривал существующие решения «псевдо-компиляции» яваскрипта и интеграции этих решений в asp.net проекты.
В итоге не найдя ничего идеального и решив, что собственный велосипед здесь не помешает, я и написал утилиту под названием jsvalidator. Найти её можно на codeplex, там же есть и краткое описание установки и конфигурирования. Данная заметка, по сути, будет переводом «официальной документации» собственного же сочинения :)
Если коротко, то jsvalidator это build-step с json-like конфигурационным файлом, проверяющая яваскрипт с помощью java-библиотеки google closure. Из этого следует и первое требование — для работы утилиты необходима установленная на компьютере java (с java.exe добавленным в системные пути (system PATH)).
После интеграции утилиты на каждый билд в вашей Visual Studio будет нечто вроде:
(в данном случае утилита сообщает нам о необъявленной переменной asd, по двойному клику на ошибке откроется js-файл на строчке с ошибкой, как мы и привыкли).
Continue reading
Unobtrusive validation и загрузка форм через аякс (full ajax website)
При использовании «ненавязчивой» (unobtrusive) валидации форм в MVC проекте можно заметить, что если валидируемая форма была подгружена асинхронно, то валидация не сработает.
Поэтому после обновления частей страницы, содержащих формы, надо не забывать выполнить что-нибудь подобное:
$.validator.unobtrusive.parse($("#loadedContent"));
(где #loadedContent — это айдишник подгруженной области).
В простейшем случае можно даже добавить этот код в обработчик события ajaxSuccess, чтобы уж точно не забыть :)
$.ajaxSuccess(function(e) { $.validator.unobtrusive.parse(document); });
P.S. Заметить факт неработоспособности клиентской валидации может с легкостью помешать принцип graceful degradation — по-умолчанию валидация отработает нормально, но это будет серверная валидация :) При тестировании на localhost это и правда можно не заметить.
Традиционный пример проекта с этой небольшой функцией.
Валидация JavaScript в ASP.Net MVC проекте — анализ существующих решений
Когда яваскрипт в веб-проекте занимает достаточно большую долю, и клиентские скрипты вырастают за рамки «инлайн-скриптов» с одной-двумя строчками вызова jquery-плагинов, вопрос о проверке и валидности яваскрипта встает достаточно явно (даже для .net-разработчиков, достаточно далеких от js в принципе :)).
Для меня эта проблема стала наиболее актуальной, когда я начал генерировать яваскрипт-хэлперы с помощью T4-шаблонов, и стало просто необходимым своевременно узнавать о том, что яваскрипт-переменная Constants.MainController.ContentId больше не существует (а была переименована в ContentsId). Также хотелось сократить цикл обнаружения банальных опечаток в названиях переменных — раньше об этом говорила консоль ошибок браузера, а хотелось видеть это на этапе билда.
В решении данной проблемы мне помогли «псевдо-компиляторы» яваскрипта, хотя, пожалуй, корректнее было бы называть их верификаторами синтаксиса.
Continue reading
Повторное использование шаблонов DisplayTemplates и EditorTemplates
При работе с шаблонами отображения и редактирования достаточно быстро возникает необходимость повторного использования однажды написанных шаблонов.
Однако, по аналогии с portable areas, при попытке выноса шаблонов в отдельную сборку возникают проблемы, связанные с тем, что MVC ищет данные шаблоны в строго отведенных местах (папка ~/Views/Shared/DisplayTemplates или ~/Views/ControllerName/EditorTemplates).
Решает эту проблему очередной open-source продукт от Дэвида Эббо — Razor Generator.
Шаблоны отображения и редактирования форм в ASP.Net MVC (DisplayTemplates/EditorTemplates)
Шаблоны отображения и редактирования — очень мощная и полезная фича ASP.Net MVC, которую я активно использую и рекомендую всем без исключения.
С помощью шаблонов можно легко и быстро отображать и редактировать модели данных, что весьма способствует быстрому прототипированию, а также помогает в случаях, когда внешний вид форм на сайте у вас более-менее стандартизован.
Предположим, что в контроллере у вас есть типичная модель регистрации:
public class RegistrationModel { public string Login { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public DateTime Birthdate { get; set; } ... }
Устранение magic-strings в javascript
Недавно я озадачился проблемой «магических строк», которые регулярно появляются в яваскрипте.
Допустим, у нас на страничке динамически генерируются блоки вида:
<span animate_period="10" animate_amplitude="20"></span>
И есть javascript-код, который ищет блоки с этими атрибутами и в соответствии со значениями применяет определенную анимацию. В итоге имена атрибутов (magic-strings по сути) дублируются во вьюшках/контроллерах и js-файлах.
Еще одной похожей проблемой становится посылка аякс-запросов к контроллерам:
$('#mydiv').load("http://mysite.ru/Items/GetItemInfo?id=20");
URL запроса явно грозит нам опечатками и/или ошибками, когда этот адрес изменится.
Если мы пишем яваскрипт-код прямо в html файлах (а не в отдельных подключаемых скрипт-файлах), то можно, конечно, воспользоваться T4MVC и написать что-то вроде:
$('#mydiv').load("@Url.Action(MVC.Items.GetItemInfo())");
Как раз о таком способе решения проблемы я недавно и писал. Но если js вы всё-таки выносите в отдельные файлы (а делать это надо — для уменьшения дублирования и клиентского кэширования), то проблема так просто не решается.
Столкнувшись с проблемой на довольно-таки большом проекте, в голову пришла мысль воспользоваться всей мощью шаблонов T4 и сгенерировать соответствующие javascript-хэлперы. Всё сложилось удачно (шаблон можно скачать), в результате обработки данного шаблона получается яваскрипт-файл T4MVC-JS.js, который можно легко инклюдить через тег <script> в хтмле, и так как он генерится не в рантайме и для Visual Studio ничем не отличается от обычного яваскрипт-файла, то по объявленным в нем переменным работает интеллисенс, что сокращает вероятность ошибок.
Continue reading