Главная страница   /   7.2. Вспомогательные методы Ajax в ASP.NET MVC (ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

Джеффри Палермо

7.2. Вспомогательные методы 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.

В зависимости от значения, установленного для UnobtrusiveJavaScriptEnabledtrue или 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: &#39;privacy&#39;
});">Show the privacy Policy</a>

Вместо атрибутов data-ajax, все метаданные находятся внутри события onclick. Оно также требует ссылки на скрипты MicrosoftAjax.js и MicrosoftMvcAjax.js для корректной работы. Данный код не является таким же интуитивным, как раньше, а также в нем нарушен принцип ненавязчивости JavaScript, так как он содержит вызов метода непосредственно в атрибуте onclick.

Если вы обновляете сайт из ранних версий ASP.NET MVC, возможно, вам потребуется сохранить данное поведение для поддержки обратной совместимости. Во всех остальных случаях лучше оставить для UnobtrusiveJavaScriptEnabled значение true, так как этот подход позволит создавать более чистую разметку и поддерживается Microsoft.