Главная страница   /   2.3. Пример приложения Guestbook (ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

ASP.NET MVC 4 в действии

Джеффри Палермо

2.3. Пример приложения Guestbook

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

Начнем мы с создания базы данных. Затем рассмотрим то, как принять введенные пользователем данные и хранить их, и, наконец, мы продемонстрируем то, как получить эти данные обратно для демонстрации их пользователю.

Создание базы данных

Большинство веб-приложений подкрепляются различного рода хранилищами данных, в роли которых могут выступать реляционные базы данных (например, Microsoft SQL Server или MySQL), документо-ориентированные базы данных (например, Raven DB, MongoDB или CouchDB) или даже обычные XML-файлы. Для нашего приложения мы будем использовать SQL Server Compact, последнее дополнение компании Microsoft к семейству реляционных баз данных SQL Server.

SQL Server Compact – это новая упрощенная база данных, которая может использоваться как с веб-приложениями, так и с настольными приложениями. В отличие от полной версии базы данных SQL Server, для запуска SQL Server Compact не требуется установка серверного программного обеспечения. Это означает, что SQL Server Compact развертывается в единственную папку bin, т.е. вы можете пользоваться базами данных SQL Server Compact, всего лишь добавив соответствующие dll-файлы в папку bin вашего проекта. Самым большим преимуществом данного подхода является тот факт, что вы можете разворачивать базы данных SQL Server Compact на любых провайдерах хостинга, запускаемых на .NET 4, без необходимости установки на этих провайдерах дополнительных компонентов.

Для того чтобы приступить к созданию базы данных, щелкните правой кнопкой мыши на папке APP_DATA и выберите команду Add, а затем пункт New Item. После этого откроется диалоговое окно Add New Item, в котором вы можете выбрать тип базы данных SQL Server Compact Database, как это показано на рисунке 2-8.

Рисунок 2-8: В данном контексте в диалоговом окне Add New Item отображаются только те элементы, которые могут быть добавлены в папку APP_DATA

Назовите базу данных Guestbook.sdf и нажмите кнопку Add.

Примечание

Если в списке доступных элементов диалогового окна Add New Item вы не видите SQL Server Compact Database, то это, вероятно, означает, что на вашем компьютере не установлен компонент SQL Server Compact для программы Visual Studio. Пожалуйста, убедитесь, что у вас установлен Service Pack 1 для программы Visual Studio 2010.

Далее мы добавим таблицу в базу данных. Для этого дважды кликните мышью по только что созданной базе данных Guestbook.sdf, после чего она откроется в окне Server Explorer. Теперь щелкните правой кнопкой мыши по элементу Tables в окне Server Explorer и выберите команду Create Table, как показано на рисунке 2-9.

Рисунок 2-9: Окно Server Explorer позволяет добавлять новые таблицы в базы данных SQL Server или SQL Server Compact

После выбора этой команды откроется диалоговое окно Create Table. В этом диалоговом окне задайте имя таблицы – GuestbookEntries. Данная таблица будет использоваться для хранения записей гостевой книги, поэтому в ней должно быть несколько колонок, включая колонки для имен пользователей, которые оставляют записи в гостевой книге, и колонки для хранения их сообщений. Нам также потребуется колонка Id в качестве первичного ключа для таблицы, а также одна колонка для даты, когда было добавлено сообщение. Для того чтобы удостовериться, что база данных автоматически увеличивает значения колонки Id на единицу после каждой вставки записи, нам необходимо будет установить значение True для свойства Identity. Формирование таблицы показано на рисунке 2-10.

Рисунок 2-10: Формирование таблицы GuestbookEntries, содержащей 4 колонки – Id, имена пользователей, оставивших записи в гостевой книге, их сообщения, а также дату, когда были добавлены сообщения

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

Добавление модели

Модель для приложения "Guestbook" будет очень простой – нам потребуется всего лишь один единственный класс, который будет олицетворять запись нашей гостевой книги. Давайте назовем этот класс GuestbookEntry, добавим его в папку Models нашего проекта, а также добавим в него несколько свойств:

public class GuestbookEntry
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Message { get; set; }
	public DateTime DateAdded { get; set; }
}

Данная модель очень проста – это всего лишь объект POCO-класса (Plain Old CLR Object), содержащий 4 свойства, совпадающих с колонками базы данных. Мы будем использовать экземпляр этого класса для обозначения данных, хранящихся в базе данных, но как нам преобразовать эти данные в объекты? Мы могли бы вручную написать код преобразования, необходимый для получения экземпляра класса GuestbookEntry из результатов SQL-запросов, но будет проще, если за нас это сделает объектно-реляционное отображение (ORM).

В нашем приложении для преобразования данных в объекты мы будем использовать Entity Framework 4.1, несмотря на то, что можно выбрать и множество других ORM-инструментов на платформе .NET (мы рассмотрим NHibernate, еще один ORM-инструмент, в главе 15). Хотя Entity Framework является достаточно обширной темой для обсуждения, которой посвящены несколько книг (к примеру, "Programming Entity Framework", написанная Юлией Лерман и "Entity Framework 4 in Action", авторами которой являются Стефано Мостарда, Марко де Санктис и Даниэль Бочикчио), Entity Framework 4.1 содержит упрощенный интерфейс, который позволяет с легкостью начать использовать Entity Framework для того, чтобы осуществить доступ к данным.

Для обеспечения возможности использования Entity Framework добавим в наше приложение класс DbContext. Класс DbContext является абстракцией Entity Framework, которая позволяет нам сохранять и извлекать данные. Создадим класс с названием GuestbookContext, который также находится в папке Models проекта нашего приложения. Реализация этого класса приведена в листинге ниже.

Листинг 2-3: Класс DbContext, используемый для взаимодействия с базой данных
using System.Data.Entity;
namespace Guestbook.Models
{
	public class GuestbookContext : DbContext
	{
		public GuestbookContext()
			: base("Guestbook")
		{
		}
		public DbSet<GuestbookEntry> Entries { get; set; }
	}
}

Строка 6: Определяет название базы данных

Строка 10: Обеспечивает доступ к данным таблицы

Варианты доступа к данным

В .NET приложениях существует множество вариантов осуществления доступа к данным. Многие современные приложения используют такие ORM-инструменты, как NHibernate или Entity Framework для доступа к реляционным базам данных, но это не единственные варианты.

Если у вас небольшое приложение, то вы можете решить, что вам не нужна дополнительная сложность, которую несет за собой использование ORM-инструментов. В таких случаях, возможно, будет удобнее использовать более простые инструменты такие, как WebMatrix.Data или Simple.Data.

WebMatrix.Data выпущен компанией Microsoft одновременно с ASP.NET MVC 3, как часть набора компонентов ASP.NET Web Pages, и является более удобным средством осуществления доступа к данным посредством использования SQL-операторов и динамических типов DLR. Simple.Data обеспечивает похожее решение, но полагается на синтаксис динамических запросов, а не на SQL-строки. Более подробную информацию о Simple.Data можно найти на сайте https://github.com/markrendle/Simple.Data.

Класс GuestbookContext наследуется от базового класса DbContext (который располагается в пространстве имен Data.Entity) и начинается с объявления конструктора, который не имеет ни одного параметра и использует конструктор связывания для передачи названия базы данных в базовый класс. В данном примере, так как наша база данных называется Guestbook.sdf, то мы в конструктор base мы передаем строку "Guestbook". Если мы не сделаем это, то Entity Framework в качестве названия базы данных будет по умолчанию использовать полный путь к классу контекста и вместо файла Guestbook.sdf будет искать файл Guestbook.Models.GuestbookContext.sdf.

Для нашего класса также определено единственное свойство Entries типа DbSet<GuestbookEntry>. Это свойство выступает в роли коллекции, которая позволяет нам запрашивать данные из таблицы "GuestbookEntries", как если бы эти данные являлись коллекцией объектов оперативной памяти. Наряду с этим Entity Framework будет генерировать соответствующий SQL-запрос к таблице базы данных и конвертировать выходные данные в строго типизированные объекты класса GuestbookEntry. То, как сформировать запрос этой коллекции, мы рассмотрим далее.

Наконец, нам необходимо сообщить Entity Framework о том, что ему необходимо связаться с базой данных SQL Server Compact (по умолчанию он будет пытаться подсоединиться к SQL Server Express).

Генерация базы данных из модели

В данном примере мы сначала создали базу данных для того, чтобы продемонстрировать, что в Visual Studio, за счет SQL Server Compact, поддерживается возможность проектирования приложения. Но создание базы данных, на самом деле, не является обязательным этапом разработки приложения.

Если бы вы попытались использовать модель без первоначального создания базы данных, то знайте, что Entity Framework достаточно умен, чтобы понять это, и он сам создал бы базу данных, таблицы и колонки, как только вы попытались бы воспользоваться своей моделью.

Для того чтобы это сделать, нам нужно добавить в приложение некоторый код инициализации. Есть несколько способов достижения этой цели. Первый заключается в добавлении кода в метод Application_Start файла Global.asax.cs вручную. Это специальный метод, который запускается при старте приложения (обычно, когда первый посетитель заходит на веб-сервер). Тем не менее, вместо того, чтобы поступить данным образом, мы воспользуемся несколько другим подходом – будем использовать менеджер NuGet для добавления кода инициализации.

NuGet – это менеджер пакетов, который позволяет легко и быстро добавлять в .NET проект библиотеки с открытым исходным кодом. Несмотря на то, что NuGet не привязывается к ASP.NET MVC проектам, он поставляется вместе с установщиком ASP.NET MVC, поэтому вы можете сразу же начать пользоваться, не устанавливая его отдельно. Данную функциональность можно найти в пакете EntityFramework.SqlServerCompact, который можно установить, нажав правой кнопкой мыши по записи References в окне Solution Explorer, и выбрав в контекстном меню пункт Manage NuGet Packages (Управление пакетами NuGet), как это показано на рисунке 2-11.

Рисунок 2-11: Пользовательский интерфейс менеджера пакетов NuGet может быть запущен с помощью Manage NuGet Packages в контекстном меню

После этого откроется диалоговое окно, где вы можете выполнить поиск пакетов в галерее NuGet. Для этого щелкните по строке Online в левой части экрана, а затем введите строку "EntityFramework.SqlServerCompact" в поле поиска в правом верхнем углу, как это показано на рисунке 2-12. Должен быть обнаружен только один пакет, который затем может быть установлен по нажатию кнопки Install.

Рисунок 2-12: Диалоговое окно Manage NuGet Packages может использоваться для установки пакетов с открытым исходным кодом в любые .NET приложения

Примечание

Так же как и диалоговое окно Manage NuGet Packages, менеджер пакетов NuGet предоставляет возможность использования оболочки интерфейса командной строки, Windows PowerShell, которая доступна в программе Visual Studio и может быть запущена с помощью выбора пункта меню View > Other Windows > Package Manager Console. Вы можете установить пакет EntityFramework.SqlServerCompact, воспользовавшись этой командной строкой вместо графического интерфейса и введя в ней команду Install-Package

После установки данный пакет автоматически добавит в проект соответствующий код, чтобы настроить Entity Framework для использования баз данных SQL Server Compact.

Использование WebActivator для регистрации кода запуска

Пакет EntityFramework.SqlServerCompact при генерации соответствующего кода запуска опирается на другой пакет с названием WebActivator. Пакет WebActivator создан Девидом Эббо, разработчиком из команды ASP.NET программистов компании Microsoft, и позволяет добавлять в приложение код инициализации без использования метода Application_Start.

При использовании пакета, который зависит от WebActivator, данный пакет создает код инициализации в папке App_Start, которая добавляется в приложение при обращении к пакету WebActivator.

WebActivator, по своей сути, является проектом с открытым исходным кодом, поэтому, если вам хочется узнать, как работает данный пакет, вы можете загрузить код с сайта https://bitbucket.org/davidebbo/webactivator.

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

Прием записей гостевой книги

Для того чтобы принять новые записи гостевой книги, мы добавим в приложение новый контроллер. Это можно сделать, щелкнув правой кнопкой мыши по папке Controllers и выбрав в контекстном меню пункт Add > Controller. После этого на экране появится диалоговое окно Add Controller (Добавление контроллера), как это показано на рисунке 2-13. Назовите контроллер GuestbookController.

Рисунок 2-13: Диалоговое окно Add Controller позволяет добавить в приложение новый контроллер, а также выполнить его настройку

Диалоговое окно Add Controller дает возможность выполнить настройку контроллера – выпадающий список Template (Шаблон) позволяет выбрать, хотите ли вы, чтобы контроллер был создан в виде пустого класса (настройка по умолчанию), или же вы хотите, чтобы автоматически были сформированы некоторые универсальные сценарии. Можно выбрать следующие 2 варианта из существующих:

  • Controller with Read/Write Actions and Views – согласно данному шаблону будут сгенерированы методы действий контроллера и представления, которые обеспечивают простую CRUD-функциональность (создание, чтение, обновление, удаление) посредством использования Entity Framework (которую мы вскоре более подробно рассмотрим).
  • Controller with Empty Read/Write Actions – при использовании этого шаблона будут сгенерированы методы действий контроллера для CRUD-сценариев, но при этом не будут создаваться представления и не будет применяться никакая конкретная технология доступа к данным.

В данном примере мы будем использовать шаблон Empty Controller, предлагаемый по умолчанию.

После того, как вы нажмете кнопку Add, новый контроллер откроется в окне редактора программы Visual Studio. Мы начнем с добавления нового метода действия в этот контроллер, которое назовем Create, как это показано ниже.

Листинг 2-4: Контроллер GuestbookController с действием Create
using System.Web.Mvc;
namespace Guestbook.Controllers
{
	public class GuestbookController : Controller
	{
		public ActionResult Create()
		{
			return View();
		}
	}
}

Метод действия Create всего лишь возвращает значение типа ViewResult, используя при этом метод View для указания на то, что фреймворк должен отобразить представление с именем Create.cshtml в подкаталоге Views/Guestbook.

Если на данном этапе вы попытаетесь получить доступ к этому действию в вашем веб-браузере, перейдя для этого по адресу http://localhost:<port>/Guestbook/Create, то вы увидите сообщение об ошибке, говорящее о том, что представление не найдено, как это показано на рисунке 2-14.

Рисунок 2-14: Если представление не найдено, то на экран выводится сообщение об ошибке

В сообщении об ошибке отображаются пути, по которым фреймворк пытался найти представление для действия Add. Заметьте, что фреймворк выполняет поиск представлений в нескольких подкаталогах с различными расширениями файлов (файлы с расширением .aspx/ascx используются в старом движке представления Web Form, с помощью которого изначально создавались представления в ASP.NET MVC 1 and 2).

Обычно фреймворк выполняет поиск представлений в подкаталоге, соответствующем контроллеру, и если он не находит представление в данном подкаталоге, то возобновляет поиск в папке Views/Shared, в которой вы можете размещать представления, используемые несколькими контроллерами.

Для того чтобы это сообщение больше не появлялось на экране, мы можем добавить представление, щелкнув правой кнопкой мыши по методу Create класса GuestbookController и выбрав пункт меню Add View, как это показано на рисунке 2-15.

Рисунок 2-15: В ASP.NET MVC добавлено несколько новых записей контекстного меню, включая возможность создавать новое представление и переходить к существующему

После выбора этого пункта меню на экране появится диалоговое окно Add View, как показано на рисунке 2-16. Оставим все установленные по умолчанию параметры неизмененными и нажмем кнопку Add.

Рисунок 2-16: Диалоговое окно Add View позволяет легко создавать новые представления, а также задавать некоторые универсальные настройки. Некоторые другие настройки мы рассмотрим в следующих главах

После добавления файла Create.cshtml мы можем добавить разметку, которая позволит пользователям размещать записи в гостевой книге, как это показано ниже.

Листинг 2-5: Содержимое метода Create представления
@{
	ViewBag.Title = "Add new entry";
}
<h2>Add new entry</h2>
<form method="post" action="">
	<fieldset>
		Please enter your name:
		<br />
		<input type="text" name="Name" maxlength="200" />
		<br />
		<br />
		Please enter your message:
		<br />
		<textarea name="Message" rows="10" cols="40">
		</textarea>
		<br />
		<br />
		<input type="submit" value="Submit Entry" />
	</fieldset>
</form>

Строка 5: Отправка формы в действие Create

Строка 9: Текстовое поле для ввода имени

Строки 14-15: Текстовое поле для ввода сообщения

Строка 18: Кнопка Submit

В представлении содержится простая HTML-форма, позволяющая пользователю вводить имя и сообщение, а также отправлять эти данные обратно в действие Create. Заметьте, что элементы формы имеют названия Name и Message, совпадающие со свойствами, которые мы определили для объекта класса GuestbookEntry. Это необходимо для упрощения процесса автоматической привязки данных, который мы рассмотрим совсем скоро.

Доступ к новому действию Create можно получить, введя в строке веб-браузера URL-адрес http://localhost:<port>/Guestbook/Create. Выходной результат данного действия показан на рисунке 2-17.

Рисунок 2-17: Метод действия Create теперь визуализирует представление, которое отображает на экране форму добавления новых записей в гостевую книгу

Теперь нам необходимо создать действие контроллера, которое будет управлять публикацией формы и вставкой данных в базу данных. Для этого мы будем использовать классы GuestbookContext и GuestbookEntry, которые мы определили ранее. Начнем с переопределения действия Create в классе GuestbookController.

Листинг 2-6: Обработка данных формы посредством метода действия контроллера.
public class GuestbookController : Controller
{
	private GuestbookContext _db = new GuestbookContext();
	public ActionResult Create()
	{
		return View();
	}
	[HttpPost]
	public ActionResult Create(GuestbookEntry entry)
	{
		entry.DateAdded = DateTime.Now;
		_db.Entries.Add(entry);
		_db.SaveChanges();
		return Content("New entry successfully added.");
	}
}

Строка 8: Ограничивает доступ только через HTTP метод POST

Строка 9: Принимает класс GuestbookEntry в качестве параметра

Строки 12-13: Сохраняет запись гостевой книги

Наше второе переопределение действия Create выделено атрибутом HttpPost, который гарантирует, что данная версия метода действия будет вызываться только в ответ на отправку формы (этот атрибут называют селектором метода действия, который мы подробнее рассмотрим в главе 16). В данном переопределении действие Create также принимает в качестве параметра объект класса GuestbookEntry, чьи свойства будут автоматически заполнены данными формы, так как названия полей формы в листинге 2-5 совпадают с названиями свойств. Такой механизм называется связывание данных модели (Model binding), и рассматривать мы его будем в главе 10.

Внутри действия Create мы можем в дальнейшем манипулировать экземпляром класса GuestbookEntry (в данном примере это осуществляется посредством установки в качестве значения свойства DateAdded текущих даты и времени) перед тем, как сохранить его. Мы сохраняем объект, для начала добавляя его в свойство EntriesDbSet класса GuestbookContext (таким образом, Entity Framework понимает, что ему необходимо отследить новую запись). Затем при помощи вызова метода SaveChanges новая запись заносится в базу данных.

Сама по себе возможность отправки сообщений не является полезной. Давайте рассмотрим то, как можно составлять список сообщений, которые уже были сохранены.

Отображение записей гостевой книги

Для отображения записей гостевой книги мы добавим в наш контроллер GuestbookController действие Index, которое будет использовать класс GuestbookContext для извлечения 20 самых последних записей и передачи их в представление. Ниже приведен код обновленного контроллера GuestbookController.

Листинг 2-7: Добавления действия Index
public class GuestbookController : Controller
{
	private GuestbookContext _db = new GuestbookContext();
	public ActionResult Index()
	{
		var mostRecentEntries =
			(from entry in _db.Entries
			 orderby entry.DateAdded descending
			 select entry).Take(20);
		ViewBag.Entries = mostRecentEntries.ToList();
		return View();
	}
	public ActionResult Create()
	{
		return View();
	}
	[HttpPost]
	public ActionResult Create(GuestbookEntry entry)
	{
		entry.DateAdded = DateTime.Now;
		_db.Entries.Add(entry);
		_db.SaveChanges();
		return RedirectToAction("Index");
	}
}

Строки 6-9: Получает самые последние записи

Строка 10: Передает записи в представление

Строка 23: Перенаправляет обратно к действию Index

В новом действии Index сначала определяется запрос получения 20 последних записей посредством первоначального упорядочивания их по дате, в которую они были добавлены, а затем получения только первых 20 записей из этого списка. Далее данный запрос исполняется, а результаты помещаются во ViewBag для того, чтобы к ним можно было получить доступ из представления. К тому же мы изменили действие Create таким образом, чтобы при создании новой записи мы перенаправлялись бы обратно в действие Index. Это выполняется посредством использования метода RedirectToAction, который указывает на то, что фреймворк должен выполнить перенаправление HTTP 302 для того, чтобы направить веб-браузер в другое местоположение.

Язык интегрированных запросов (Language Integrated Query или LINQ)

Запрос в действии Index, приведенный в листинге 2-7, определяется при помощи синтаксиса языка интегрированных запросов (LINQ), который впервые был введен как часть C# 3 в .NET 3.5. LINQ позволяет определять строго типизированные запросы, которые могут выполняться с различными источниками данных.

В данном примере LINQ провайдер для Entity Framework будет конвертировать запрос в подходящие SQL-операторы, необходимые для извлечения данных из базы данных SQL Server Compact.

Нам также необходимо будет создать соответствующее представление для этого действия. И снова такое представление можно создать, дважды щелкнув правой кнопкой мыши на действии Index и выбрав в контекстном меню пункт Add View для создания файла Index.cshtml в соответствующем местоположении. Код для данного представления представлен ниже:

Листинг 2-8: Отображение записей гостевой книги
@{
	ViewBag.Title = "List";
}
<h2>My Guestbook Entries</h2>
<p>
	<a href="/Guestbook/Create">Add a new entry</a>
</p>
@foreach (var entry in ViewBag.Entries) 
{
	<section class="contact">
		<header>
			<h3>@entry.Message</h3>
		</header>
		<p>
			Posted by @entry.Name on @entry.DateAdded.ToLongDateString()
		</p>
	</section>
}

Помимо того, что в этом представлении содержится ссылка на добавление новой записи, данное представление также заносит работу с каждой добавленной в объект ViewBag записью в цикл и считывает сообщения, имя автора и дату сообщения, в которую оно было добавлено. Вы можете просмотреть результат, перейдя к новому действию в подкаталоге /Guestbook/Index. Выходной результат показан на рисунке 2-18.

Рисунок 2-18: Веб-страница отображает самые последние записи гостевой книги

На данный момент мы закончили реализацию основной функциональности, необходимой для приложения "Guestbook" – мы можем и отправлять, и просматривать записи гостевой книги. Но нам еще много чего предстоит сделать. Для начала давайте удалим сообщение "My MVC Application" из строки заголовка.

Настройка внешнего вида и поведения представления с помощью макетов

Представления, которые мы видели до этого, включают в себя содержимое, являющееся специфичным для каждой конкретной страницы. Внешний вид страницы (к примеру, меню и заголовок) определяется в макете. Макет может применяться для того, чтобы иметь возможность использовать универсальные элементы пользовательского интерфейса, которые являются общими для всех страниц (если вы пользуетесь предыдущими версиями ASP.NET MVC или ASP.NET Web Forms, то макет является аналогом Master Page (Мастера страницы)). Давайте рассмотрим то, как мы можем изменить макет, чтобы в приложении отображался другой заголовок и дополнительные пункты меню для просмотра записей гостевой книги, как это показано на рисунке 2-19.

Рисунок 2-19: Обновленный макет содержит новый заголовок и новый пункт меню

Для редактирования макета страницы приложения откройте файл _Layout.cshtml, расположенный в подкаталоге Views\Shared. Содержимое данного файла приведено в листинге ниже.

Листинг 2-9: Макет, используемый по умолчанию
<!DOCTYPE html>
<html lang="en">
<head>
	...
</head>
<body>
	<header>
		<div class="content-wrapper">
			<div class="float-left">
				<p class="site-title">
					@Html.ActionLink("your logo here.",
						"Index", "Home")
				</p>
			</div>
			<div class="float-right">
				<section id="login">
					Hello, <span class="username">@Html.Partial("_LogOnPartial")</span>!
				</section>
				<nav>
					<ul id="menu">
						<li>@Html.ActionLink("Home", "Index", "Home")</li>
						<li>@Html.ActionLink("About", "About", "Home")</li>
						<li>@Html.ActionLink("View Entries", "Index",
							"Guestbook")</li>
					</ul>
				</nav>
			</div>
		</div>
	</header>
	<div id="body">
		@RenderSection("featured", required: false)
		<section class="content-wrapper main-content clear-fix">
			@RenderBody()
		</section>
	</div>
	<footer>
		...
	</footer>
</body>
</html>

Строка 4: Задает импортирование CSS и скриптов

Строка 12: Устанавливает заголовок страницы

Строка 17: Выводит частичное представление

Строки 20-25: Определяет пункты меню

Строки 31-33: Выводит содержимое страницы

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

Для изменения заголовка приложения нам необходимо просто заменить содержимое тега <h1> на выбранную нами строку (в данном примере давайте будем использовать строку "My Guest Book").

В этом файле есть еще несколько интересных вещей. Ссылка Log On, которую вы видите в приложении, использующем макет, заданный по умолчанию, выводится посредством частичного представления. Мы рассмотрим частичные представления в главе 3, но по своей сути они дают возможность повторного использования блоков HTML-разметки в сложных страницах.

Меню приложения также включено в файл Site.css. Оно выводится в виде неупорядоченного списка, в котором элементы списка содержат ссылки на различные действия. Вместо того чтобы использовать жестко закодированные ссылки, мы можем воспользоваться вспомогательным HTML-методом ActionLink для вывода гиперссылки на конкретное действие контроллера. Мы рассмотрим эти вспомогательные методы в следующей главе, но использовать их мы можем начать прямо сейчас. Для добавления нового пункта меню, используемого для списка записей гостевой книги, мы просто вставим следующий кусок кода:

<li>@Html.ActionLink("View Entries", "Index", "Guestbook")</li>

С помощью этого кода будет сгенерирована новая ссылка на страницу записей. Первым аргументом метода ActionLink является текст, который будет отображаться в гиперссылке, второй аргумент – название метода, с которым мы хотим связать эту гиперссылку, а третий – название контроллера, в котором расположено данное действие.

Последней интересной вещью в этом файле является вызов метода RenderBody. Данный метод вставляет содержимое текущего представления так, чтобы макет включал разметку, сгенерированную действиями конкретного представления и которую мы создали ранее.

После того, как мы задали заголовок страницы и необходимый пункт меню, мы можем переходить к следующей теме.