Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core
Теперь рассмотрим на практике работу Web API. Создадим новое приложение MVC 5 по типу Web API. Назовем его, его например, BookingApp:
И вначале определим класс модели, с объеками которой будет работать приложение. Этот класс по традиции будет описывать книгу. Итак, добавим в папку Models новый класс Book:
public class Book { public int Id { get; set; } public string Name { get; set; } public string Author { get; set; } public int Year { get; set; } }
Если проект по умолчанию не содержит библиотек EF, установим через NuGet пакет Entity Framework в проект и добавим в папку Models класс контекста данных BookContext:
using System.Data.Entity; namespace BookingApp.Models { public class BookContext : DbContext { public DbSet<Book> Books { get; set; } } }
В файле web.config установим подключение к базе данных, которая будет хранить все объекты:
<connectionStrings> <add name="BookContext" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename='|DataDirectory|\BookDB.mdf';Integrated Security=True" /> </connectionStrings>
Теперь для начальной работы инициализируем базу данных некоторыми начальными данными. Мы можем либо создать базу данных вручную и добавить в нее данные, либо можно использовать инициализатор баз данных. Воспользуемся вторым способом. Добавим в папку Models следующий класс:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Data.Entity; namespace BookingApp.Models { public class BookDbInitializer : DropCreateDatabaseAlways<BookContext> { protected override void Seed(BookContext db) { db.Books.Add(new Book { Name = "Война и мир", Author = "Л. Толстой", Year = 1863 }); db.Books.Add(new Book { Name = "Отцы и дети", Author = "И. Тургенев", Year = 1862 }); db.Books.Add(new Book { Name = "Чайка", Author = "А. Чехов", Year = 1896 }); base.Seed(db); } } }
И подключим инициализатор в файле Global.asax:
......................... using BookingApp.Models; using System.Data.Entity; namespace BookingApp { public class WebApiApplication : System.Web.HttpApplication { protected void Application_Start() { Database.SetInitializer(new BookDbInitializer()); AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); } } }
Теперь перейдем к созданному по умолчанию контроллеру ValuesController и изменим его следующим образом:
using System; using System.Collections.Generic; using System.Linq; using System.Data.Entity; using System.Net; using System.Net.Http; using System.Web.Http; using BookingApp.Models; using System.Data; namespace BookingApp.Controllers { public class ValuesController : ApiController { BookContext db = new BookContext(); public IEnumerable<Book> GetBooks() { return db.Books; } public Book GetBook(int id) { Book book = db.Books.Find(id); return book; } [HttpPost] public void CreateBook([FromBody]Book book) { db.Books.Add(book); db.SaveChanges(); } [HttpPut] public void EditBook(int id, [FromBody]Book book) { if (id == book.Id) { db.Entry(book).State = EntityState.Modified; db.SaveChanges(); } } public void DeleteBook(int id) { Book book = db.Books.Find(id); if(book!=null) { db.Books.Remove(book); db.SaveChanges(); } } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } }
Таким образом, получится контроллер, реализующий CRUD-модель, то есть добавление, получение, обновление и удаление данных.
Но то же самое мы могли бы сделать автоматически, использовав шаблоны формирования при создании контроллера. Для этого просто при создании нового API-контроллера укажем модель и класс контекста данных, которые будут использоваться (перед использованием модели приложение необходимо скомпилировать):
И шаблон формирования создаст нам аналогичный функционал с небольшими изменениями в коде. И также управляя опциями шаблона формирования, мы можем указать, что мы хотим контроллер с асинхронными действиями.
Итак, теперь мы можем перейти к построению клиентской части, но перед этим протестируем приложение. Для тестирования воспользуемся браузером, например, Internet Explorer, который может дать нам полную информацию о запросе с помощью средств разработчика:
По умолчанию при запуске проекта идет обращение к другому стандартному контроллеру HomeController и его методу Index, которое возвращает представление.
Нам пока это представление не интересует. Обратимся к контроллеру Web API. Для этого отправим запрос api/values/ (в моем случае
полный запрос выглядит следующим образом:http://localhost:1479/api/values/). Поскольку этот запрос представляет запрос GET,
то данный запрос будет обрабатываться методом public IEnumerable<Book> GetBooks()
, возвращающим все объекты из БД.
После этого браузер предложит нам сохранить файл json со всеми объектами, которые были получены из базы данных:
[{ "Id":1,"Name":"Война и мир", "Author":"Л. Толстой", "Year":1863 },{ "Id":2, "Name":"Отцы и дети", "Author":"И. Тургенев", "Year":1862 },{ "Id":3, "Name":"Чайка", "Author":"А. Чехов", "Year":1896 }]
При использовании других браузеров (Firefox, Google Chrome) мы получим те же данные, только в формате xml.
Таким образом, мы убедились, что приложение работает. И теперь перейдем к построению клиентской части приложения.