Главная страница   /   25.3. Создание API контроллера (ASP.NET MVC 4

ASP.NET MVC 4

ASP.NET MVC 4

Адам Фриман

25.3. Создание API контроллера

Теперь мы готовы определить Web API, который будем использовать в коде JavaScript для взаимодействия с содержимым хранилища. В этом разделе мы добавим в проект API Controller и объясним, как он работает.

Для создания контроллера кликните правой кнопкой мыши по папке Controllers в окне Solution Explorer и выберите Add - Controller из контекстного меню. В поле Controller name введите ReservationController и выберите Empty API controller из выпадающего списка Template, как показано на рисунке 25-2.

Рисунок 25-2: Добавляем новый контроллер API в проект

Опция Empty API controller создает контроллер API без методов действий. В выпадающем списке доступны несколько других опций, которые будут создавать контроллеры API с шаблонными методами действий, которые можно заполнить. Но мы предпочитаем начинать с пустого класса и определять функции, которые нам нужны. Начальный класс контроллера, созданный Visual Studio, показан в листинге 25-7.

Листинг 25-7: Контроллер, который создает опция Empty API Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace WebServices.Controllers
{
	public class ReservationController : ApiController
	{
	}
}

Мы выделили базовый класс контроллера Reservation, потому что в нем заметны отличия от обычного контроллера. System.Web.Http.ApiController реализует интерфейс IController, описанный в главе 15, но совершенно иначе обрабатывает запросы, чем обычный класс System.Web.Mvc.Controller, который был основой для всех других примеров в этой книге (за исключением того, где мы создали собственную реализацию IController). В листинге 25-8 показано, как мы добавили в контроллер Reservation хранилище и определили методы действий Web API, которые потребуются для доступа к объектам Reservation.

Листинг 25-8: Завершаем контроллер API Reservation
using System.Collections.Generic;
using System.Web.Http;
using WebServices.Models;

namespace WebServices.Controllers
{
	public class ReservationController : ApiController
	{
		private IReservationRepository repo = ReservationRepository.getRepository();

		public IEnumerable<Reservation> GetAllReservations()
		{
			return repo.GetAll();
		}

		public Reservation GetReservation(int id)
		{
			return repo.Get(id);
		}

		public Reservation PostReservation(Reservation item)
		{
			return repo.Add(item);
		}

		public bool PutReservation(Reservation item)
		{
			return repo.Update(item);
		}

		public void DeleteReservation(int id)
		{
			repo.Remove(id);
		}
	}
}

Это все, что требуется для создания Web API. Мы создали экземпляр нашего класса хранилища и пять методов действий, которые обеспечивают доступ к объектам модели Reservation, которые содержаться в хранилище.

Подсказка

Обратите внимание, что для получения IReservationRepository мы вызываем статический метод ReservationRepository.getRepository. Для обслуживания запросов к API создаются новые экземпляры контроллеров, и, если бы нам нужно было создать новый объект ReservationRepository в самом контроллере, наши изменения никак не отразились бы на данных, отправляемых клиенту. Это особенность нашего хранилища «в памяти» - такого не будет происходить при работе с реальными хранилищами, которые сохраняют данные в базах.

Тестируем контроллер API

Мы вскоре расскажем, как работает контроллер API, но перед этим выполним простой тест. Запустите приложение. Когда браузер загрузит корневой URL проекта, перейдите по ссылке /api/reservation. Результат, который вы увидите, будет зависеть от вашего браузера. Если вы используете Internet Explorer 10, то вам будет предложено сохранить или открыть файл, который содержит следующие данные JSON:

[{"ReservationId":1,"ClientName":"Adam","Location":"London"},
{"ReservationId":2,"ClientName":"Steve","Location":"New York"},
{"ReservationId":3,"ClientName":"Jacqui","Location":"Paris"}]

Если перейти по той же ссылке в другом браузере, например, Google Chrome или Mozilla Firefox, то браузер отобразит следующие данные XML:

<ArrayOfReservation>
	<Reservation>
		<ClientName>Adam</ClientName>
		<Location>London</Location>
		<ReservationId>1</ReservationId>
	</Reservation>
	<Reservation>
		<ClientName>Steve</ClientName>
		<Location>New York</Location>
		<ReservationId>2</ReservationId>
	</Reservation>
	<Reservation>
		<ClientName>Jacqui</ClientName>
		<Location>Paris</Location>
		<ReservationId>3</ReservationId>
	</Reservation>
</ArrayOfReservation>

Здесь можно отметить несколько интересных моментов. Во-первых, наш запрос к ссылке /api/reservation вернул список всех наших объектов модели и их свойств, из чего мы делаем вывод, что был вызван метод действия GetAllReservations в контроллере Reservation.

Во-вторых, разные браузеры получили разные форматы данных. Если вы сами попробуете перейти по ссылке из разных браузеров, то получите разные результаты, потому что более поздние версии браузеров могут иначе отправлять запросы; в любом случае вы увидите, что один запрос вернул JSON, другой - XML. (Вы также можете понять, почему JSON в значительной степени заменил XML в веб-службах. XML использует более подробную разметку и его труднее обрабатывать, особенно если вы используете JavaScript).

Различные форматы данных используются потому, что Web API использует заголовок HTTP Accept, содержащийся в запросе, чтобы узнать, с каким типом данных клиент предпочел бы работать. Internet Explorer получает JSON, потому что он посылает следующий заголовок:

Accept: text/html, application/xhtml+xml, */*

Браузер указал, что он прежде всего он предпочитает работать с форматом text/html, далее - application/xhtml+xml. В конце заголовка указано */*, что означает, что браузер примет любой тип данных, если первые два недоступны.

Web API поддерживает JSON и XML, но отдает предпочтение JSON, который и использует в ответе, опираясь на часть заголовка Accept */*. Вот заголовок Accept, который отправляет Google Chrome:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Здесь мы выделили важную деталь: Chrome сообщил, что он предпочитает получать данные application/xml всем остальным. Web API учитывает это предпочтение и отправляет данные XML.

Мы останавливаемся на этом потому, что общая проблема при работе с Web API - получение нежелательного формата данных. Так происходит потому, что в заголовке Accept указывается неправильное предпочтение формата, или оно вообще отсутствует.