Самое время перейти к разработке демонстрационного проекта. Для этого поставим задачу – создать каталог книг. Несмотря на простоту, он послужит хорошим примером для изучения ASP.NET MVC 3.
Начнем с создания пустого проекта BookCatalog. Этот процесс уже был описан во второй части, поэтому не будем останавливаться на нем подробно.
Согласно идеологии MVC в Модели содержится вся бизнес-логика будущего веб-приложения: от описания используемых данных до алгоритмов, ответственных за представляемую пользователю функциональность. Поэтому и начнем разработку с её классов.
Проектируем Модель
Давайте определим набор данных, который будет соответствовать описанию книги в базе данных создаваемого веб-приложения:
- уникальный код в локальной базе данных (Id);
- название (Title);
- автор или авторы (Author);
- язык, на котором она написана (Language);
- издатель (Publisher);
- дата выхода (PublishedAt);
- ссылка на сайт книги (для бесплатных изданий) или на онлайн-магазин (для коммерческих) (Url);
- краткое описание (Description);
- ключевые слова (Tags);
- рейтинг (Rating);
- признак того, что книга доступна бесплатно (IsFree);
- признак того, что запись о книге может быть отображена в каталоге (IsVisible).
Здесь можно отметить три свойства, которые желательно задавать из готового перечня значений: Language, Publisher и Tags. Для хранения из значений разработаем дополнительные классы с соответствующими именами.
В папке Models создадим следующие файлы:
- Tag.cs – класс для хранения ключевых слов:
namespace BookCatalog.Models
{
using System.Collections.Generic;
public class Tag
{
public int Id { get; set; }
public string Text { get; set; }
public virtual ICollection<BookDetails> Books { get; set; }
}
}
В данном классе свойство Books предназначено для получения списка книг, которым было присвоено выбранное ключевое слово.
- Language.cs – класс для хранения названий языков:
namespace BookCatalog.Models
{
using System.Collections.Generic;
public class Language
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<BookDetails> Books { get; set; }
}
}
- Publisher.cs – класс содержащий информацию об издательстве:
namespace BookCatalog.Models
{
using System.Collections.Generic;
public class Publisher
{
public int Id { get; set; }
public string Title { get; set; }
public string Homepage { get; set; }
public virtual ICollection<BookDetails> Books { get; set; }
}
}
В данном случае свойство Books, которое возвращает коллекцию книг, выпущенных издательством.
- BookDetails.cs – класс, содержащий информацию о книге:
namespace BookCatalog.Models
{
using System;
using System.Collections.Generic;
public class BookDetails
{
public int Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public int LanguageId { get; set; }
public int? PublisherId { get; set; }
public DateTime PublishedAt { get; set; }
public string Url { get; set; }
public string Description { get; set; }
public int? Rating { get; set; }
/// <summary>Gets or sets a value indicating whether
/// the book is free (true) or not (false).</summary>
public bool IsFree { get; set; }
/// <summary>Gets or sets a value indicating whether
/// the book is visible in the catalog (true) or not (false).</summary>
public bool IsVisible { get; set; }
public virtual ICollection<Tag> Tags { get; set; }
public virtual Language Language { get; set; }
public virtual Publisher Publisher { get; set; }
}
}
Давайте рассмотрим некоторые свойства отдельно:
- Для указания языка и издателя используются свойства LanguageId и PublisherId, которые будут содержать идентификаторы из соответствующих списков. Кроме того, для них добавлены "спутники" Language и Publisher указывающие на соответствующие экземпляры данных классов.
- Свойство PublisherId может принимать значение null, что будет обозначать отсутствие издателя. Это может потребоваться, например, если это книга опубликованная на сайте автора.
Важный момент: после создания или изменения модели необходимо скомпилировать проект. Это необходимо для того, чтобы были созданы или обновлены сборки. Тогда помощники, которые будут использоваться в дальнейшем, смогут использовать актуальную информацию о классах проекта. В частности, это относится к диалогу создания Представлений.
А что дальше?
Следующим шагом в разработке должно стать создание Контроллеров и Представлений. Для этого можно поступить аналогично рассмотренному в прошлой части варианту и самостоятельно написать весь код. Но это достаточно трудоемкий способ для относительно однообразной работы.
Другим вариантом будет использование готовых шаблонов, поставляемых с ASP.NET MVC 3. Для этого необходимо в диалоге создания Контроллера в качестве Template выбрать: Controller with read/write actions and views, using Entity Framework.
В этом случае помощник ASP.NET MVC 3 создаст Представления и Контроллер. В последний будет добавлен исходный код для взаимодействия с базой данных с применением Entity Framework. Рассмотрим работу этой библиотеки позже, а пока просто взглянем на методы полученного в результате класса Контроллера:
//
// GET: /Catalog/Edit/5
public ActionResult Edit(int id)
{
BookDetails bookdetails = db.BookDetails.Find(id);
ViewBag.LanguageId = new SelectList(db.Languages, "Id", "Name", bookdetails.LanguageId);
ViewBag.PublisherId = new SelectList(db.Publishers, "Id", "Title", bookdetails.PublisherId);
return View(bookdetails);
}
//
// POST: /Catalog/Edit/5
[HttpPost]
public ActionResult Edit(BookDetails bookdetails)
{
if (ModelState.IsValid)
{
db.Entry(bookdetails).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.LanguageId = new SelectList(db.Languages, "Id", "Name", bookdetails.LanguageId);
ViewBag.PublisherId = new SelectList(db.Publishers, "Id", "Title", bookdetails.PublisherId);
return View(bookdetails);
}
В примере выше представлены два метода, созданные помощником ASP.NET MVC 3 и относящиеся к Действию Edit. Как можно легко заметить, в коде раскрываются детали работы с базой данных и библиотекой Entity Framework. Такой подход может в дальнейшем способствовать переносу логики приложения в Контроллер, что противоречит сути шаблона MVC.
Вполне логично было бы использовать шаблон Repository, подразумевающий более абстрактную работу с источником данных. Конечно, можно все сделать вручную. К счастью, этом случае есть более удобное решение – давайте сократим срок начальной разработки и применим заготовки (scaffolding).
Исходный код проекта (C#, Visual Studio 2010):
mvc3-in-depth-basics-05.zip