Поделиться через


Итерация 7. Добавление функций Ajax (C#)

от Майкрософт

Скачивание кода

В седьмой итерации мы повышаем скорость реагирования и производительность приложения, добавляя поддержку Ajax.

Создание приложения MVC для управления контактами ASP.NET (C#)

В этой серии учебников мы создадим все приложение управления контактами от начала до конца. Приложение Диспетчер контактов позволяет хранить контактные данные ( имена, номера телефонов и адреса электронной почты) для списка людей.

Мы создаем приложение с помощью нескольких итераций. С каждой итерацией мы постепенно улучшаем приложение. Цель этого подхода с несколькими итерациями — дать возможность понять причину каждого изменения.

  • Итерация 1. Создание приложения. В первой итерации мы создадим диспетчер контактов самым простым способом. Добавлена поддержка базовых операций с базами данных: создание, чтение, обновление и удаление (CRUD).

  • Итерация 2. Сделайте приложение красивым. В этой итерации мы улучшаем внешний вид приложения, изменив ASP.NET по умолчанию представление MVC master страницу и каскадную таблицу стилей.

  • Итерация 3. Добавление проверки формы. В третьей итерации мы добавим базовую проверку формы. Мы запрещаем пользователям отправлять форму без заполнения обязательных полей формы. Мы также проверяем адреса электронной почты и номера телефонов.

  • Итерация 4. Сделайте приложение слабосвязанным. В этой четвертой итерации мы воспользуемся преимуществами нескольких шаблонов проектирования программного обеспечения, чтобы упростить обслуживание и изменение приложения Диспетчера контактов. Например, мы рефакторинг приложения для использования шаблона репозитория и шаблона внедрения зависимостей.

  • Итерация 5. Создание модульных тестов. В пятой итерации мы упростим обслуживание и изменение приложения, добавив модульные тесты. Мы имитируем классы модели данных и создаем модульные тесты для наших контроллеров и логики проверки.

  • Итерация 6. Использование разработки на основе тестирования. В этой шестой итерации мы добавим новые функции в приложение, сначала написав модульные тесты и написав код для модульных тестов. В этой итерации мы добавим группы контактов.

  • Итерация 7. Добавление функциональных возможностей Ajax. В седьмой итерации мы повышаем скорость реагирования и производительность приложения, добавляя поддержку Ajax.

Эта итерация

В этой итерации приложения Диспетчера контактов мы рефакторингуем приложение для использования Ajax. Используя Ajax, мы делаем наше приложение более быстрым. Мы можем избежать отрисовки всей страницы, если нам нужно обновить только определенный регион на странице.

Мы будем рефакторинговать представление индекса, чтобы не переигрывать всю страницу, когда кто-то выбирает новую группу контактов. Вместо этого, когда кто-то щелкает группу контактов, мы просто обновим список контактов и оставим остальную часть страницы в покое.

Мы также изменим способ работы ссылки на удаление. Вместо отображения отдельной страницы подтверждения мы выведем диалоговое окно подтверждения JavaScript. Если вы подтвердите удаление контакта, на сервере выполняется операция HTTP DELETE для удаления записи контакта из базы данных.

Кроме того, мы воспользуемся преимуществами jQuery для добавления эффектов анимации в представление индекса. Мы будем отображать анимацию при получении нового списка контактов с сервера.

Наконец, мы воспользуемся поддержкой платформы ASP.NET AJAX для управления журналом браузера. Мы будем создавать точки журнала при каждом вызове Ajax для обновления списка контактов. Таким образом, будут работать кнопки браузера назад и вперед.

Зачем использовать Ajax?

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

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

В приложении Ajax не нужно останавливать взаимодействие с пользователем только для обновления страницы. Вместо этого можно выполнить асинхронный запрос в фоновом режиме, чтобы обновить страницу. Вы не заставляете пользователя ждать, пока часть страницы будет обновлена.

Используя Ajax, вы также можете повысить производительность приложения. Подумайте, как приложение Диспетчера контактов работает прямо сейчас без функциональных возможностей Ajax. При выборе группы контактов необходимо перезапустить все представление индекса. Список контактов и список групп контактов должны быть получены с сервера базы данных. Все эти данные должны передаваться по сети от веб-сервера к веб-браузеру.

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

Не бойтесь Ajax

Некоторые разработчики избегают использования Ajax, так как они беспокоятся о браузерах нижнего уровня. Они хотят убедиться, что их веб-приложения по-прежнему будут работать при доступе из браузера, который не поддерживает JavaScript. Так как Ajax зависит от JavaScript, некоторые разработчики не используют Ajax.

Однако если вы будете осторожны с реализацией Ajax, вы можете создавать приложения, которые работают как с браузерами на uplevel, так и на нижнем уровнях. Наше приложение Диспетчер контактов будет работать с браузерами, поддерживающими JavaScript, и браузерами, которые этого не делают.

Если вы используете приложение Диспетчера контактов с браузером, поддерживающим JavaScript, то у вас будет более удобное взаимодействие с пользователем. Например, при выборе группы контактов обновляется только регион страницы, на котором отображаются контакты.

С другой стороны, если вы используете приложение Диспетчера контактов с браузером, который не поддерживает JavaScript (или для которого отключен JavaScript), у вас будет немного менее удобный пользовательский интерфейс. Например, при выборе группы контактов все представление индекса должно быть опубликовано в браузере, чтобы отобразить соответствующий список контактов.

Добавление необходимых файлов JavaScript

Для добавления функций Ajax в приложение потребуется использовать три файла JavaScript. Все эти три файла включены в папку Scripts нового приложения ASP.NET MVC.

Если вы планируете использовать Ajax на нескольких страницах в приложении, имеет смысл включить необходимые файлы JavaScript в представление приложения master страницу. Таким образом, файлы JavaScript будут автоматически включены во все страницы приложения.

Добавьте следующие элементы JavaScript в <тег head> master страницы представления:

<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
    <script src="../../Scripts/jquery-1.2.6.min.js" type="text/javascript"></script>

Рефакторинг представления индекса для использования Ajax

Начнем с изменения представления индекса, чтобы при щелчке группы контактов обновлялись только области представления, в котором отображаются контакты. Красный прямоугольник на рис. 1 содержит регион, который требуется обновить.

Обновление только контактов

Рис. 01. Обновление только контактов (щелкните для просмотра полноразмерного изображения)

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

Листинг 1. Views\Contact\ContactList.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactManager.Models.Group>" %>
<%@ Import Namespace="Helpers" %>
<table class="data-table" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th class="actions edit">
                Edit
            </th>
            <th class="actions delete">
                Delete
            </th>
            <th>
                Name
            </th>
            <th>
                Phone
            </th>
            <th>
                Email
            </th>
        </tr>
    </thead>
    <tbody>
        <% foreach (var item in Model.Contacts)
           { %>
        <tr>
            <td class="actions edit">
                <a href='<%= Url.Action("Edit", new {id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
            </td>
            <td class="actions delete">
                <a href='<%= Url.Action("Delete", new {id=item.Id}) %>'><img src="../../Content/Delete.png" alt="Edit" /></a>
            </td>
            <th>
                <%= Html.Encode(item.FirstName) %>
                <%= Html.Encode(item.LastName) %>
            </th>
            <td>
                <%= Html.Encode(item.Phone) %>
            </td>
            <td>
                <%= Html.Encode(item.Email) %>
            </td>
        </tr>
        <% } %>
    </tbody>
</table>

Обратите внимание, что часть в листинге 1 имеет модель, отличную от модели представления индекса. Атрибут Inherits в директиве <%@ Page %> указывает, что часть наследуется от класса ViewUserControl<Group> .

Обновленное представление индекса содержится в листинге 2.

Листинг 2. Views\Contact\Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
    <li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
    <%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList"})%>
    </li>
<% } %>
</ul>
<div id="divContactList">
    <% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>

<div class="divContactList-bottom"> </div>
</asp:Content>

В листинге 2 об обновленном представлении следует обратить внимание на две вещи. Во-первых, обратите внимание, что все содержимое, перемещенное в часть, заменяется вызовом Html.RenderPartial(). Метод Html.RenderPartial() вызывается при первом запросе представления индекса для отображения начального набора контактов.

Во-вторых, обратите внимание, что элемент Html.ActionLink(), используемый для отображения групп контактов, был заменен на Ajax.ActionLink(). Ajax.ActionLink() вызывается со следующими параметрами:

<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList"})%>

Первый параметр представляет текст, отображаемый для ссылки, второй параметр представляет значения маршрута, а третий параметр представляет параметры Ajax. В этом случае мы используем параметр UpdateTargetId Ajax, чтобы указать <html-тег div> , который требуется обновить после завершения запроса Ajax. Мы хотим обновить <тег div> , указав новый список контактов.

Обновленный метод Index() контроллера Contact содержится в листинге 3.

Листинг 3. Controllers\ContactController.cs (метод Index)

public ActionResult Index(int? id)
{
    // Get selected group
    var selectedGroup = _service.GetGroup(id);
    if (selectedGroup == null)
        return RedirectToAction("Index", "Group");

    // Normal Request
    if (!Request.IsAjaxRequest())
    {
        var model = new IndexModel
        {
            Groups = _service.ListGroups(),
            SelectedGroup = selectedGroup
        };
        return View("Index", model);
    }

    // Ajax Request
    return PartialView("ContactList", selectedGroup);
}

Обновленное действие Index() условно возвращает одну из двух вещей. Если действие Index() вызывается запросом Ajax, контроллер возвращает часть. В противном случае действие Index() возвращает все представление.

Обратите внимание, что действию Index() не нужно возвращать столько данных при вызове запросом Ajax. В контексте обычного запроса действие Индекс возвращает список всех групп контактов и выбранной группы контактов. В контексте запроса Ajax действие Index() возвращает только выбранную группу. Ajax означает меньше работы на сервере базы данных.

Измененное представление индекса работает в браузерах как на более, так и на более нижнем уровнях. Если щелкнуть группу контактов и браузер поддерживает JavaScript, обновляется только регион представления, содержащий список контактов. Если, с другой стороны, ваш браузер не поддерживает JavaScript, то все представление обновляется.

В обновленном представлении индекса есть одна проблема. Если щелкнуть группу контактов, выбранная группа не будет выделена. Так как список групп отображается за пределами региона, который обновляется во время запроса Ajax, правильная группа не будет выделена. Мы устраним эту проблему в следующем разделе.

Добавление эффектов анимации jQuery

Обычно при щелчке ссылки на веб-странице можно использовать индикатор выполнения браузера, чтобы определить, активно ли браузер извлекает обновленное содержимое. С другой стороны, при выполнении запроса Ajax индикатор выполнения браузера не отображает ход выполнения. Это может заставить пользователей нервничать. Как узнать, завис браузер?

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

Для создания эффектов анимации мы будем использовать библиотеку jQuery, которая входит в состав платформы Microsoft ASP.NET MVC. Обновленное представление индекса содержится в листинге 4.

Листинг 4. Views\Contact\Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<script type="text/javascript">

    function beginContactList(args) {
        // Highlight selected group
        $('#leftColumn li').removeClass('selected');
        $(this).parent().addClass('selected');

        // Animate
        $('#divContactList').fadeOut('normal');
    }

    function successContactList() {
        // Animate
        $('#divContactList').fadeIn('normal');
    }

    function failureContactList() {
        alert("Could not retrieve contacts.");
    }

</script>

<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
    <li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
    <%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>
    </li>
<% } %>
</ul>
<div id="divContactList">
    <% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>

<div class="divContactList-bottom"> </div>
</asp:Content>

Обратите внимание, что обновленное представление индекса содержит три новые функции JavaScript. Первые две функции используют jQuery для исчезания и исчезания в списке контактов при выборе новой группы контактов. Третья функция отображает сообщение об ошибке, когда запрос Ajax приводит к ошибке (например, время ожидания сети).

Первая функция также выполняет выделение выбранной группы. Атрибут class= selected добавляется к родительскому элементу (элементу LI) выбранного элемента. Опять же, jQuery позволяет легко выбрать нужный элемент и добавить класс CSS.

Эти скрипты привязаны к ссылкам групп с помощью параметра Ajax.ActionLink() AjaxOptions. Обновленный вызов метода Ajax.ActionLink() выглядит следующим образом:

<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>

Добавление поддержки журнала браузера

Как правило, при щелчке по ссылке для обновления страницы обновляется журнал браузера. Таким образом, можно нажать кнопку Назад браузера, чтобы вернуться к предыдущему состоянию страницы. Например, если щелкнуть группу контактов "Друзья", а затем выбрать группу Деловые контакты, можно нажать кнопку Назад в браузере, чтобы вернуться к состоянию страницы, когда была выбрана группа контактов "Друзья".

К сожалению, выполнение запроса Ajax не обновляет журнал браузера автоматически. Если щелкнуть группу контактов и получить список соответствующих контактов с помощью запроса Ajax, журнал браузера не обновляется. Вы не можете использовать кнопку Назад браузера, чтобы вернуться к группе контактов после выбора новой группы контактов.

Если вы хотите, чтобы пользователи могли использовать кнопку Назад браузера после выполнения запросов Ajax, вам нужно выполнить немного больше работы. Необходимо воспользоваться функциями управления журналом браузера, встроенными в ASP.NET AJAX Framework.

ASP.NET журнале браузера AJAX необходимо выполнить три действия:

  1. Включите журнал браузера, задав для свойства enableBrowserHistory значение true.
  2. Сохранение точек журнала при изменении состояния представления путем вызова метода addHistoryPoint().
  3. Восстановление состояния представления при возникновении события навигации.

Обновленное представление индекса содержится в листинге 5.

Листинг 5. Views\Contact\Index.aspx

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<ContactManager.Models.ViewData.IndexModel>" %>
<%@ Import Namespace="Helpers" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<title>Index</title>
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<script type="text/javascript">

    var _currentGroupId = -1;

    Sys.Application.add_init(pageInit);

    function pageInit() {
        // Enable history
        Sys.Application.set_enableHistory(true);

        // Add Handler for history
        Sys.Application.add_navigate(navigate);
    }

    function navigate(sender, e) {
        // Get groupId from address bar
        var groupId = e.get_state().groupId;

        // If groupId != currentGroupId then navigate
        if (groupId != _currentGroupId) {
            _currentGroupId = groupId;
            $("#divContactList").load("/Contact/Index/" + groupId);
            selectGroup(groupId);
        }
    }

    function selectGroup(groupId) {
        $('#leftColumn li').removeClass('selected');
        if (groupId)
            $('a[groupid=' + groupId + ']').parent().addClass('selected');
        else
            $('#leftColumn li:first').addClass('selected');
    }

    function beginContactList(args) {
        // Highlight selected group
        _currentGroupId = this.getAttribute("groupid");
        selectGroup(_currentGroupId);

        // Add history point
        Sys.Application.addHistoryPoint({ "groupId": _currentGroupId });

        // Animate
        $('#divContactList').fadeOut('normal');
    }

    function successContactList() {
        // Animate
        $('#divContactList').fadeIn('normal');
    }

    function failureContactList() {
        alert("Could not retrieve contacts.");
    }

</script>

<ul id="leftColumn">
<% foreach (var item in Model.Groups) { %>
    <li <%= Html.Selected(item.Id, Model.SelectedGroup.Id) %>>
    <%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new { groupid = item.Id })%>
    </li>
<% } %>
</ul>
<div id="divContactList">
    <% Html.RenderPartial("ContactList", Model.SelectedGroup); %>
</div>

<div class="divContactList-bottom"> </div>
</asp:Content>

В листинге 5 в функции pageInit() включен журнал браузера. Функция pageInit() также используется для настройки обработчика событий для события navigate. Событие навигации возникает всякий раз, когда кнопка браузера "Вперед" или "Назад" приводит к изменению состояния страницы.

Метод beginContactList() вызывается при выборе группы контактов. Этот метод создает новую точку журнала путем вызова метода addHistoryPoint(). Идентификатор группы контактов, нажатой, добавляется в журнал.

Идентификатор группы извлекается из атрибута expando по ссылке группы контактов. Ссылка отображается с помощью следующего вызова Ajax.ActionLink().

<%= Ajax.ActionLink(item.Name, "Index", new { id = item.Id }, new AjaxOptions { UpdateTargetId = "divContactList", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" }, new {groupid=item.Id})%>

Последний параметр, переданный в Ajax.ActionLink(), добавляет атрибут expando с именем groupid в ссылку (в нижнем регистре для совместимости XHTML).

Когда пользователь нажимает кнопку браузера Назад или Вперед, возникает событие navigate и вызывается метод navigate(). Этот метод обновляет контакты, отображаемые на странице, в соответствии с состоянием страницы, которое соответствует точке журнала браузера, переданной методу navigate.

Выполнение операций удаления Ajax

В настоящее время, чтобы удалить контакт, необходимо щелкнуть ссылку Удалить, а затем нажать кнопку Удалить, отображаемую на странице подтверждения удаления (см. рис. 2). Это похоже на множество запросов страниц для выполнения простых действий, таких как удаление записи базы данных.

Страница подтверждения удаления

Рис. 02. Страница подтверждения удаления (щелкните для просмотра полноразмерного изображения)

Заманчиво пропустить страницу подтверждения удаления и удалить контакт непосредственно из представления индекса. Следует избегать этого искушения, так как такой подход открывает в приложении пробелы в безопасности. Как правило, не требуется выполнять операцию HTTP GET при вызове действия, которое изменяет состояние веб-приложения. При удалении необходимо выполнить операцию HTTP POST или, что еще лучше, операцию HTTP DELETE.

Ссылка Удалить содержится в элементе ContactList. Обновленная версия части ContactList содержится в листинге 6.

Листинг 6. Views\Contact\ContactList.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<ContactManager.Models.Group>" %>
<%@ Import Namespace="Helpers" %>
<table class="data-table" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th class="actions edit">
                Edit
            </th>
            <th class="actions delete">
                Delete
            </th>
            <th>
                Name
            </th>
            <th>
                Phone
            </th>
            <th>
                Email
            </th>
        </tr>
    </thead>
    <tbody>
        <% foreach (var item in Model.Contacts)
           { %>
        <tr>
            <td class="actions edit">
                <a href='<%= Url.Action("Edit", new {id=item.Id}) %>'><img src="../../Content/Edit.png" alt="Edit" /></a>
            </td>
            <td class="actions delete">
            <%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })%> 
            </td>
            <th>
                <%= Html.Encode(item.FirstName) %>
                <%= Html.Encode(item.LastName) %>
            </th>
            <td>
                <%= Html.Encode(item.Phone) %>
            </td>
            <td>
                <%= Html.Encode(item.Email) %>
            </td>
        </tr>
        <% } %>
    </tbody>
</table>

Ссылка Delete отображается с помощью следующего вызова метода Ajax.ImageActionLink():

<%= Ajax.ImageActionLink("../../Content/Delete.png", "Delete", "Delete", new { id = item.Id }, new AjaxOptions { Confirm = "Delete contact?", HttpMethod = "Delete", UpdateTargetId = "divContactList" })%>

Примечание

Ajax.ImageActionLink() не является стандартной частью платформы ASP.NET MVC. Ajax.ImageActionLink() — это настраиваемые вспомогательные методы, включенные в проект Диспетчера контактов.

Параметр AjaxOptions имеет два свойства. Во-первых, свойство Confirm используется для отображения всплывающего диалогового окна подтверждения JavaScript. Во-вторых, свойство HttpMethod используется для выполнения операции HTTP DELETE.

В листинге 7 содержится новое действие AjaxDelete(), добавленное в контроллер contact.

Листинг 7. Controllers\ContactController.cs (AjaxDelete)

[AcceptVerbs(HttpVerbs.Delete)]
[ActionName("Delete")]
public ActionResult AjaxDelete(int id)
{
    // Get contact and group
    var contactToDelete = _service.GetContact(id);
    var selectedGroup = _service.GetGroup(contactToDelete.Group.Id);

    // Delete from database
    _service.DeleteContact(contactToDelete);

    // Return Contact List
    return PartialView("ContactList", selectedGroup);
}

Действие AjaxDelete() украшено атрибутом AcceptVerbs. Этот атрибут предотвращает вызов действия, за исключением операций HTTP, отличных от операции HTTP DELETE. В частности, это действие нельзя вызвать с помощью HTTP GET.

После удаления записи базы данных необходимо отобразить обновленный список контактов, который не содержит удаленную запись. Метод AjaxDelete() возвращает частичный и обновленный список контактов ContactList.

Итоги

В этой итерации мы добавили функцию Ajax в приложение Диспетчера контактов. Мы использовали Ajax для повышения скорости отклика и производительности приложения.

Во-первых, мы рефакторинговали представление индекса, чтобы при щелчке группы контактов не обновлялось все представление. Вместо этого при выборе группы контактов обновляется только список контактов.

Далее мы использовали эффекты анимации jQuery, чтобы исчезать и исчезать в списке контактов. Добавление анимации в приложение Ajax можно использовать для предоставления пользователям приложения эквивалента индикатора выполнения браузера.

Мы также добавили поддержку журнала браузера в наше приложение Ajax. Мы позволили пользователям нажимать кнопки браузера Назад и Вперед, чтобы изменить состояние представления индекса.

Наконец, мы создали ссылку на удаление, которая поддерживает операции HTTP DELETE. Благодаря удалению Ajax пользователи могут удалять записи базы данных без необходимости запрашивать дополнительную страницу подтверждения удаления.