Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Одним из преимуществ стека технологий на платформе .NET является возможность создания сервисов. Так, в ASP.NET мы могли создавать ASMX-веб-службы. Кроме того, мы можем использовать более функциональную в этом плане технологию WCF для создания веб-служб.
Но с последним релизом MVC 4 и вообще всей платформы .NET 4.5 в нашем распоряжении оказался еще один инструмент для создания веб-служб - Web API. Концепция Web API (которую кстати можно использовать не только в MVC, но и в веб-формах) новый подход к реализации веб-приложений.
Создадим простое приложение ASP.NET MVC 4, указав в качестве шаблона проекта Web API:
Среда создаст обычный mvc-проект со стандартной структурой. По умолчанию нам будет создано два контроллера. Один из них стандартный контроллер HomeController. Второй контроллер - ValuesController, который и реализует функционал Web API:
public class ValuesController : ApiController { // GET api/values public IEnumerable<string> Get() { return new string[] { "value1", "value2" }; } // GET api/values/5 public string Get(int id) { return "value"; } // POST api/values public void Post([FromBody]string value) { } // PUT api/values/5 public void Put(int id, [FromBody]string value) { } // DELETE api/values/5 public void Delete(int id) { } }
Как видно, определение контроллера Web API отличается от обычного контроллера. Во-первых, он образован от класса ApiController
,
который не связан с базовым классом обычных контроллеров - Controller
Во-вторых, контроллеры Web API применяют стиль REST. Вообще поддержка архитектуры REST (Representation State Transfer или "передача состояния представления") является одним из основных узловых пунктов технологии Web API.
Для взаимодействия с сервером в REST-архитектуре используются методы HTTP:
GET
POST
PUT
DELETE
У нас тут нет обычных методов действий, как в традиционных контроллерах, которые возвращают ActionResult. А определенные в контроллере ValuesContoller методы сопоставляются с одноименными методами HTTP.
Поскольку в Web API методы контроллера не являются прямыми ресурсами и сопоставляются с методами HTTP, то и весь механизм маршрутизации действует не как при определении обычных маршрутов. Все определения маршрутов для Web API находятся в файле WebApiConfig.cs (в папке App_Start):
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
В данном случае определен один маршрут, где в качестве второго параметра выступает контроллер, а третий необязательный параметр представляет некоторый идентификатор. Таким образом, в отличие от маршрутов обычных контроллеров у нас здесь нет действия, только контроллер и дополнительный необязательный параметр
В итоге обращение api/values будет соответствовать обращению к контроллеру ValuesCotroller, причем почти ко всем действиям сразу (кроме Get(int id) - так как в данном случае необходим еще идентификатор, например api/values/2)
Но, как уже выше говорилось, в зависимости от использованного метода HTTP фреймворк будет различать к какому именно действию относится текущий запрос.
Так, например, запрос GET api/values будет сопоставлен с методом IEnumerable<string> Get()
и вернет в ответ браузеру
коллекцию элементов string
.
Если же сервер получит запрос PUT с адресом api/values, то такой запрос будет сопоставлен с методом Put.
А запросу GET api/values/7 будет соответствовать метод string Get(int id)
, так как этот метод принимает параметр.
При создании методов контроллера Web API действует некоторые условности. Так, имена методов по умолчанию должны начинаться с имени предназначенного для них метода HTTP. В случае с контроллером по умолчанию все просто: все методы действий носят названия методов HTTP.
Однако мы можем использовать и любые другие имена без префиксов, но в этом случае нам надо будет явно указать метод HTTP в виде атрибута, например:
public class ValuesController : ApiController { public IEnumerable<string> GetAllItems() { return new string[] { "value1", "value2" }; } public string GetItem(int id) { return "value"; } [HttpPost] public void CreateItem([FromBody]string value) { } [HttpPut] public void EditItem(int id, [FromBody]string value) { } [HttpDelete] public void RemoveItem(int id) { } }
Таким образом, если первые два действия соответствуют соглашениям о наименовании (в начале содержат название метода HTTP), то к остальным мы применяем атрибуты, чтобы система знала, с каким методом надо сопоставлять запрос.