ASP.NET MVC 4 в действии
Джеффри Палермо
Вспомогательные методы Ajax в ASP.NET MVC
Ранее в этой главе мы узнали, как можно написать клиентский код JavaScript для отправки и получения данных с сервера. Однако существует еще один подход для отправки запросов Ajax в ASP.NET MVC, который предполагает использование вспомогательных методов Ajax. Для начала мы рассмотрим вспомогательные методы Ajax, доступные в ASP.NET MVC, и как они связаны с jQuery и другими библиотеками JavaScript. Далее мы узнаем, как их можно использовать для достижения тех же результатов, которые мы получали до сих пор, когда записывали код jQuery вручную.
Эти вспомогательные методы доступны как методы расширения в классе AjaxHelper
, и они будут полезны для создания разметки, которая автоматически использует Ajax для отправки и получения данных. Они приведены в таблице 7.1.
Таблица 7-1: Вспомогательные методы Ajax
Вспомогательный метод | Описание |
Ajax.ActionLink |
Создает гиперссылку на действие контроллера, которая при нажатии отправляет запрос Ajax. |
Ajax.RouteLink |
Похож на Ajax.ActionLink , но создает ссылку на определенный роут, а не действие контроллера |
Ajax.BeginForm |
Создает элемент формы, который будет отправлять введенные данные к определенному действию контроллера |
Ajax.BeginRouteForm |
Похож на Ajax.BeginForm , но отправляет запрос по определенному роуту, а не к действию контроллера |
Ajax.GlobalizationScript |
Создает ссылку на скрипт глобализации, в котором содержится информация о языке и региональных параметрах |
Ajax.JavaScriptStringEncode |
Кодирует строку для безопасного использования в JavaScript |
Хотя последние два способа фактически не относятся к Ajax, их можно эффективно использовать при работе с JavaScript в приложениях MVC.
Данные вспомогательные методы Ajax используют библиотеки JavaScript для отправления актуальных запросов. Эта разметка не привязана напрямую к какой-либо библиотеке, а использует адаптеры, позволяющие использовать библиотеку JavaScript для отправки запросов Ajax. В коробочной версии ASP.NET MVC есть адаптеры для JQuery и Microsoft Ajax. То, какой из них будет использован, зависит от конфигурации приложения.
Когда вы создаете новый проект ASP.NET MVC, файл web.config
содержит следующие строки:
<appSettings>
<add key="UnobtrusiveJavaScriptEnabled" value="true"/>
</appSettings>
При такой настройке разметка, созданная вспомогательными методами Ajax, использует ненавязчивый JavaScript, аналогично примерам с jQuery в предыдущем разделе. Однако когда этот параметр отключен, вспомогательные методы будут создавать разметку, которая использует библиотеку MicroSoft Ajax. Лучше всего оставить этот параметр включенным. Что произойдет, если вы выставите ему значение false
, мы разберем далее.
Примечание
Вместо настройки параметра
UnobtrusiveJavaScriptEnabled
в файлеweb.config
вы также можете настроить статическое свойствоHtmlHelper.UnobtrusiveJavaScriptEnabled
в методеApplication_Start
в файлеGlobal.asax
.
В зависимости от значения, установленного для UnobtrusiveJavaScriptEnabled
– true
или false
, вспомогательные методы Ajax в ASP.NET MVC будут создавать разметку, совместимую с конкретным адаптером. Этот адаптер знает, как ее обрабатывать, и вызывает соответствующую библиотеку JavaScript для исполнения кода. Отношения между вспомогательными методами Ajax и библиотеками JavaScript показаны на рисунке 7-5.
Рисунок 7-5: Отношения между вспомогательными методами Ajax и библиотеками JavaScript
Для начала возьмем пример страницы Privacy Policy из предыдущего раздела и рассмотрим, как можно использовать метод ActionLink
для достижения того же результата. Контроллер изменять не нужно, но в представление Index
понадобится внести изменения, показанные в следующем листинге.
Листинг 7-8: Использование Ajax.ActionLink
@section head {
<script type="text/javascript"
src="@Url.Content(
"~/scripts/jquery.unobtrusive-ajax.js")">
</script>
}
@Ajax.ActionLink(
"Show the privacy Policy",
"PrivacyPolicy",
new AjaxOptions {
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "privacy"
})
<div id="privacy"></div>
Строка 1: Представление в разделе
head
Строки 2-5: Ссылка на скрипт
jQuery.unobtrusive
Строка 8: Определяет текст гиперссылки
Строка 9: Ссылка на действие
Строка 10-12: Дополнительные опции
Как и в предыдущих примерах, мы начнем с отображения части раздела head
. Но на этот раз мы добавим ссылку на файл jQuery.unobtrusive-ajax.js
, который также является частью шаблона проекта ASP.NET MVC по умолчанию. Это адаптер, который знает, как использовать JQuery для выполнения Ajax запросов, основываясь на представляемых элементах.
Затем мы добавим вызовAjax.ActionLink
. Для этого метода есть несколько перегруженных вариантов. Мы используем вариант с тремя аргументами. Первый – это текст, который должен стать гиперссылкой. Второй - название действия, к которому должен быть отправлен асинхронный запрос - в нашем случае, действие PrivacyPolicy
. Последний аргумент - это объект AjaxOptions
, который можно использовать для настройки запроса. Свойство UpdateTargetId
этого объекта указывает, что HTML-элемент с id
равном privacy
нужно обновить, чтобы добавить результат запроса к действию PrivacyPolicy
, и свойство InsertionMode
указывает, что все содержимое этого элемента необходимо заменить.
Когда вы запустите приложение, вы получите такой же результат, как и в предыдущем примере – информация о политике конфиденциальности добавляется на страницу под ссылкой на действие. Но представленная разметка выглядит несколько иначе:
<a data-ajax="true" data-ajax-mode="replace"
data-ajax-update="#privacy"
href="/AjaxHelpers/PrivacyPolicy">Show the privacy Policy</a>
В предыдущем примере мы использовали JQuery, чтобы найти на странице ссылку с конкретным ID и прикрепить к ней обработчик события. Ajax.ActionLink
генерирует ссылки, используя несколько иной подход.
Эти ссылки имеют несколько дополнительных атрибутов. Именно наличие этих атрибутов указывает, что данная ссылка должна быть обработана Ajax. Таким образом, вместо создания запроса Ajax в специальном файле JavaScript, мы добавляем в ссылку все метаданные, необходимые сценарию JQuery-unobtrusive.ajax
для того, чтобы создать соответствующий запрос.
Атрибут data-ajax
указывает, что гиперссылка должна выполнять свою функцию асинхронно, а атрибуты data-ajax-mode
и data-ajax-update
относятся к объекту AjaxOptions
, указанному в листинге 7.8.
Когда страница загрузится, скрипт в файле jquery-unobtrusive.ajax
найдет все ссылки с атрибутом data-ajax
и добавит событие click
, что похоже на то, что мы делали в листинге 7.7. Аналогично, если в браузере отключен JavaScript, то ссылка продолжит функционировать как обычная гиперссылка, не использующая Ajax.
data-атрибуты HTML5
Атрибуты
data-*
, такие какdata-ajax
иdata-ajax-update
, известны как data-атрибуты HTML5. Они предоставляют возможность добавить дополнительные метаданные к HTML-элементу. Хотя здесь они используются для предоставления информации об Ajax-запросе, вы можете написать свои атрибуты для любых метаданных, к которым потребуется доступ на стороне клиента.Хотя эти пользовательские атрибуты считаются частью спецификации HTML5, они будут работать без проблем на старых браузерах, которые не поддерживают HTML5 (в том числе Internet Explorer 6).
Ajax.BeginForm
Таким же образом вы можете использовать вспомогательный метод Ajax.BeginForm
для асинхронной отправки формы. Давайте изменим форму, которую мы предварительно создали для добавления комментариев, используя этот вспомогательный метод.
Листинг 7-9: Форма с Ajax
<h4>Comments</h4>
<ul id="comments"></ul>
@using(Ajax.BeginForm("AddComment", new AjaxOptions {
UpdateTargetId = "comments",
InsertionMode = InsertionMode.InsertAfter })) {
@Html.TextArea("Comment", new{rows=5, cols=50})
<br />
<input type="submit" value="Add Comment" />
}
Строка 3: Помещает форму в блок
using
Строка 6: Текстовая область для комментариев
Как и метод Html.BeginForm
, который мы изучили в главе 2, метод Ajax.BeginForm
используется в блоке using
, чтобы определить размер формы. Запрос к BeginForm
отображает открывающий тег <form />
, а закрывающая скобка блока using
определяет конец тега.
Перегруженный вариант, который мы используем в данный момент для BeginForm
, принимает два параметра. Первый – это имя действия контроллера, который мы вызываем (в данном случае AddComment
), второй – объект AjaxOptions
. Как и в методе Ajax.ActionLink
, эти параметры определяют, как должен быть обработан результат Ajax-запроса. В этом случае после того, как запрос отправлен, результат должен быть загружен в конец списка comments
.
Как и форма из листинга 7.6, эта форма содержит текстовую область и кнопку отправки.
Если сейчас запустить приложение, оно будет работать точно так же, хотя к форме и добавлены дополнительные атрибуты data-ajax
, такие как ActionLink
. Результат разметки приведен в листинге 7-10.
Листинг 7-10: Разметка Ajax.BeginForm
<form action="/AjaxHelpers/AddComment"
data-ajax="true" data-ajax-method="POST"
data-ajax-mode="after" data-ajax-update="#comments"
id="form0" method="post">
<textarea cols="50" id="Comment" name="Comment" rows="5">
</textarea>
<br />
<input type="submit" value="Add Comment" />
</form>
В этой форме также реализуется принцип прогрессивного улучшения. Когда скрипт jQuery.unobtrusiveаjax
включен в страницу, эта форма будет отправлена через Ajax, но если в браузере пользователя отключен JavaScript, форма выполнит обычную отправку данных.
Параметры Ajax
В предыдущем разделе было показано, что во вспомогательных методах ActionLink
и BeginForm
может использоваться объект AjaxOptions
. Он содержит указания, как должен быть обработан результат запроса Ajax. Класс AjaxOptions
содержит несколько параметров, доступных как свойства; они перечислены в таблице 7-2.
Таблица 7-2: Свойства класса AjaxOptions
Параметр | Описание |
HttpMethod |
Указывает HTTP-метод GET или POST . Если не указано иное, по умолчанию задает POST для форм и GET для ссылок. |
UpdateTargetId |
Указывает элемент, в который должна быть вставлена результирующая разметка. |
InsertionMode |
Задает режим вставки: InsertBefore (вставить содержимое перед существующими дочерними элементами целевого элемента), InsertAfter (вставить содержимое после существующих дочерних элементов) или Replace (полностью заменить внутреннее содержимое элемента). |
OnBegin |
Определяет функцию JavaScript, которую нужно вызвать перед отправкой запроса к действию. |
OnComplete |
Определяет функцию JavaScript, которую нужно вызвать после получения ответа сервера. |
OnFailure |
Определяет функцию JavaScript, которая вызывается в случае ошибки. |
OnSuccess |
Определяет JavaScript функцию, которая будет вызвана, если ошибок нет. |
Confirm |
Устанавливает подтверждающее сообщение, которое будет отображаться в диалоговом окне OK/Cancel, прежде чем исполнение кода будет продолжено. |
URL |
Задает URL для случая, если тег привязки указывает иное направление, чем запрос Ajax. |
LoadingElementId |
Указывает элемент, который отображает прогресс Ajax. Элемент должен быть изначально помечен как display:none . |
LoadingElementDuration |
Определяет продолжительность анимации для отображения или скрытия загружающегося элемента, если был указан LoadingElementId . |
За исключением LoadingElementDuration
, все эти параметры были ранее доступны в ASP.NET MVC 2. Теперь изменился только способ, каким они добавляются в разметку страницы. Как вы уже знаете, эти параметры генерируются как data-
атрибуты в HTML-элементах, тогда как в MVC 2 они добавлялись на страницу гораздо более навязчивым образом.
Отличия от предыдущих версий ASP.NET MVC
Хотя вспомогательные методы Ajax и были частью ASP.NET MVC начиная с первой версии, теперь по умолчанию используется jQuery. В предыдущих версиях платформы эти вспомогательные методы всегда использовали библиотеку Microsoft Ajax и не генерировали JavaScript в ненавязчивой форме. Вы можете вернуться к этому поведению, назначив параметру UnobtrusiveJavaScriptEnabled
значение false
в разделе AppSettings
в файле web.config
:
<appSettings>
<add key="UnobtrusiveJavaScriptEnabled" value="false"/>
</appSettings>
Теперь, если мы отправляем запрос к Ajax.ActionLink
таким же образом, как мы сделали это в листинге 7-8, будет генерироваться следующая разметка:
<a href="/AjaxHelpers/PrivacyPolicy"
onclick="Sys.Mvc.AsyncHyperlink.handleClick(
this, new Sys.UI.DomEvent(event), {
insertionMode: Sys.Mvc.InsertionMode.replace,
updateTargetId: 'privacy'
});">Show the privacy Policy</a>
Вместо атрибутов data-ajax
, все метаданные находятся внутри события onclick
. Оно также требует ссылки на скрипты MicrosoftAjax.js
и MicrosoftMvcAjax.js
для корректной работы. Данный код не является таким же интуитивным, как раньше, а также в нем нарушен принцип ненавязчивости JavaScript, так как он содержит вызов метода непосредственно в атрибуте onclick
.
Если вы обновляете сайт из ранних версий ASP.NET MVC, возможно, вам потребуется сохранить данное поведение для поддержки обратной совместимости. Во всех остальных случаях лучше оставить для UnobtrusiveJavaScriptEnabled
значение true
, так как этот подход позволит создавать более чистую разметку и поддерживается Microsoft.