Наверное, уже не существует веб разработчика, который не слышал о Ajax. Microsoft в такой ситуации не может оставаться в стороне, с каждым релизом старается облегчить жизнь именно нам, ASP.NET MVC разработчикам. Но прежде чем я продолжу статью, немного отступлюсь от темы.
Когда я познакомился с MVC фреймворком, он был тогда только во второй версии и, столкнувшись с такими хелперами как
Начну с того, что MVC может работать с двумя вариантами Ajax библиотек (конечно я же имею ввиду с коробки, не более того) — jQuery и Microsoft Ajax. Чтобы знать, для какого адаптера создавать разметку, существует настройка в
В зависимости от того, каков вариант вам более по душе, вам необходимо подключить соответствующий адаптер. Для Microsoft Ajax
, a для jQuery
Как я писал выше, вариант с jQuery меня вполне устраивает. Поэтому пойду по пути ненавязчивого JavaScript (т.е.
Рассмотрим такую задачу. Есть ссылочка, при клике на которую мы хотим обновить содержимое контейнера. Что делал я ранее.
Кусочек метода действия
Большинству знаком такой вспомогательный метод как
Вуаля,
Разница между двумя расширенными методами

Как видно свойств, в принципе, у него не много, с другой стороны это и хорошо, когда начинают создавать серебряную пулю, будь то объект или библиотека, становится просто не вероятно громоздкой и неработоспособной.
Что из свойств за что отвечает, лучше MSDN я сказать не смогу.

Давайте пробежимся по свойствам:
Под конец хотелось бы привести табличку методов, которые нам время от времени облегчат нашу жизнь
Рассмотрим такую ситуацию. Ajax запрос возвращает JSON/XML/Частичное представление — и все хорошо, но такой подход совсем не приемлем, если пользователь отключил JavaScript, либо браузер вообще не поддерживает его. В таких случаях необходимо полностью вернуть страницу пользователю. Одним из решений является вариант использования «разводки» в одном методе действия с определением того, является ли этот запрос запросом Ajax. Это можно сделать, используя
Вторым вариантом решения проблемы является создание двух разных методов действия: одного — для Ajax запроса, а второго — для обычного. Давайте рассмотрим этот вариант подробнее, на упрощенной задаче сохранения полученного от пользователя комментария.
Создаем два метода действия
представление
и наше представление с формой
Для браузера рендерится следующая форма
Мы видим, что отличие от
Целью моей статьи было лишь показать, что некоторые вещи можно немного ускорить и не изобретать велосипед (сужу лишь по себе).
На написание этой статьи меня сподвигли главы книг:
Ajax в ASP.NET MVC (ASP.NET MVC 4 в действии)
и
Вспомогательные методы для URL и Ajax (pro ASP.NET MVC 4)
Когда я познакомился с MVC фреймворком, он был тогда только во второй версии и, столкнувшись с такими хелперами как
@Ajax....
, честно говоря, их реализация на стороне клиента меня не впечатлила. Нет, так нет, подумал я про себя, у меня есть jQuery со своим $.ajax
, мне его за глаза. Вот и забыл я про них на несколько лет, к своему великому сожалению проморгав этот момент с третьим релизом. Что было, то было. Благо что взялся за ум и почитал две книги по MVC 4. Далее расскажу, как можно сократить написание строк кода благодаря хелперам, упомянутым мною выше.Начну с того, что MVC может работать с двумя вариантами Ajax библиотек (конечно я же имею ввиду с коробки, не более того) — jQuery и Microsoft Ajax. Чтобы знать, для какого адаптера создавать разметку, существует настройка в
web.config
UnobtrusiveJavaScriptEnabled
и соответствующее значение true
(для работы с jQuery) и false
(для работы с Microsoft Ajax). Если же нам необходимо поменять значение только для одного представления, можно воспользоваться методом — @{Html.EnableUnobtrusiveJavaScript(bool);}
. Хочу обратить внимание, что данная настройка влияет и на формирование валидационных данных на стороне клиента.В зависимости от того, каков вариант вам более по душе, вам необходимо подключить соответствующий адаптер. Для Microsoft Ajax
<script src="~/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="~/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
, a для jQuery
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"></script>
Как я писал выше, вариант с jQuery меня вполне устраивает. Поэтому пойду по пути ненавязчивого JavaScript (т.е.
web.config
с />
), и начну с самого простого.ActionLink
Рассмотрим такую задачу. Есть ссылочка, при клике на которую мы хотим обновить содержимое контейнера. Что делал я ранее.
Кусочек метода действия
public ActionResult Index()
{
if (Request.IsAjaxRequest())
return PartialView("_IndexPartial");
return View();
}
Index
преставление<script type="text/javascript">
jQuery(function($) {
$('#update-container').click(function(e) {
e.preventDefault();
$.ajax({
url: '@Url.Action("Index", "Home")',
success: function(data) {
$('#container').html(data);
}
});
})
})
</script>
<div id="container">
@Html.Partial("_IndexPartial")
</div>
@Html.ActionLink("Поменять данные", "Index", "Home", new {}, new {id = "update-container"})
_IndexPartial
частичное представление<div>Динамическое данные в зависимости от запроса</div>
Большинству знаком такой вспомогательный метод как
Html. ActionLink(...)
, представленный выше. Казалось бы, строк кода в принципе не много, да и привык так уже программировать, так что все в порядке, но ведь я очень ленивый программист и в меру своих сил борюсь за чистоту и уменьшение кода. Поэтому мне будет приятно уменьшить представление с 22 строк до 5. И на помощь ко мне приходит Ajax.ActionLink(...)
(конечно, скептики могут сказать, что вместо $.ajax
можно было использовать .load
или $.get
, но сути это не меняет, мы сократили представление, которое и так порой у нас начинает пухнуть)Вуаля,
Index
преставление<div id="container">
@Html.Partial("_IndexPartial")
</div>
@Ajax.ActionLink("Поменять данные", "Index", "Home", new {}, new AjaxOptions{UpdateTargetId = "container"}, new {id = "update-container"}) //id элемента нам уже не нужно, но для наглядности оставлю
Разница между двумя расширенными методами
Html.ActionLink
и Ajax.ActionLink
заключается только в одном параметре, объекте AjaxOptions
. Давайте о нем и поговорим.AjaxOptions

Как видно свойств, в принципе, у него не много, с другой стороны это и хорошо, когда начинают создавать серебряную пулю, будь то объект или библиотека, становится просто не вероятно громоздкой и неработоспособной.
Что из свойств за что отвечает, лучше MSDN я сказать не смогу.

Давайте пробежимся по свойствам:
Confirm
— аналог javascript confirm(...)
HttpMethod
— типа string
, самое интересное, что же MS заставило ограничиться только 2 методами, ума не приложу почему, и видимо алгоритм таков, все что не GET
, null
или пустая строка после .Trim()
— все POST
InsertionMode
— перечисление со значениями "InsertAfter
" (вставить в конец контейнера), "InsertBefore
" (вставить в начало контейнера) или "Replace
" (заменить содержимое контейнера)Loading...
— изначальный скрытый элементOn.....
— javascript функции, по аналогии с $.ajax
OnBegin
—beforeSend
OnComplete
—complete
OnFailure
—error
OnSuccess
—success
Url
— ссылка на отдельный адрес ajax запроса, если нам необходимо развести запрос от ajax запроса по разным роутам/контроллерам/действиям/параметрам (нужное подчеркнуть)Ajax вспомогательные методы
Под конец хотелось бы привести табличку методов, которые нам время от времени облегчат нашу жизнь
Ajax.ActionLink |
Создает гиперссылку на действие контроллера, которая при нажатии отправляет запрос Ajax. |
Ajax.RouteLink |
Похож на Ajax.ActionLink , но создает ссылку на определенный роут, а не действие контроллера |
Ajax.BeginForm |
Создает элемент формы, который будет отправлять введенные данные к определенному действию контроллера |
Ajax.BeginRouteForm |
Похож на Ajax.BeginForm , но отправляет запрос по определенному роуту, а не к действию контроллера |
Ajax.GlobalizationScript |
Создает ссылку на скрипт глобализации, в котором содержится информация о языке и региональных параметрах |
Ajax.JavaScriptStringEncode |
Кодирует строку для безопасного использования в JavaScript |
Обеспечение постепенного ухудшения
Рассмотрим такую ситуацию. Ajax запрос возвращает JSON/XML/Частичное представление — и все хорошо, но такой подход совсем не приемлем, если пользователь отключил JavaScript, либо браузер вообще не поддерживает его. В таких случаях необходимо полностью вернуть страницу пользователю. Одним из решений является вариант использования «разводки» в одном методе действия с определением того, является ли этот запрос запросом Ajax. Это можно сделать, используя
Request.IsAjaxRequest()
, как было рассмотрено выше.Вторым вариантом решения проблемы является создание двух разных методов действия: одного — для Ajax запроса, а второго — для обычного. Давайте рассмотрим этот вариант подробнее, на упрощенной задаче сохранения полученного от пользователя комментария.
Создаем два метода действия
[HttpPost]
public ActionResult AddComment(string comment)
{
//необходимые действия
return View();
}
[HttpPost]
public ActionResult AddCommentAjax(string comment)
{
//необходимые действия
return Json(new {resultMessage = "Ваш комментарий добавлен успешно!"});
}
представление
AddComment
<h3>Ваш комментарий добавлен успешно!</h3>
и наше представление с формой
<script type="text/javascript">
function OnSuccessComment(data) {
alert(data.resultMessage);
}
</script>
@using (Ajax.BeginForm("AddComment", new AjaxOptions
{
Url = Url.Action("AddCommentAjax"),
OnSuccess = "OnSuccessComment",
HttpMethod = "POST"
}))
{
@Html.TextArea("comment")
<input type="submit" value="Добавить комментарий"/>
}
Как это работает
Для браузера рендерится следующая форма
<form id="comment-form" action="/Home/AddComment" method="POST" data-ajax-url="/Home/AddCommentAjax" data-ajax-success="OnSuccessComment" data-ajax-method="POST" data-ajax="true">
<textarea rows="2" name="comment" id="comment" cols="20"></textarea>
<input type="submit" value="Добавить комментарий">
</form>
Мы видим, что отличие от
@using (Html.BeginForm("AddComment", "Home"))
заключается только в дополнительных data-
атрибутах. Иными словами, для отключенного Javascript форма будет отравляться на public ActionResult AddComment(string comment)
. Когда же JavaScript включен, адаптер считывает данные с data-
атрибутов, перехватывает отправку формы и делает запрос на public ActionResult AddCommentAjax(string comment)
. Успешный результат мы получаем в виде переданного JSON и обрабатываем в указанной js функции OnSuccessComment
.Резюме
Целью моей статьи было лишь показать, что некоторые вещи можно немного ускорить и не изобретать велосипед (сужу лишь по себе).
На написание этой статьи меня сподвигли главы книг:
Ajax в ASP.NET MVC (ASP.NET MVC 4 в действии)
и
Вспомогательные методы для URL и Ajax (pro ASP.NET MVC 4)