Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ASP_NET_MVC_4_Framework_s_primerami_na_C_dlya_p

.pdf
Скачиваний:
25
Добавлен:
19.03.2016
Размер:
17.66 Mб
Скачать

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

Мы могли бы до конца этой главы создавать доменную модель и хранилище, даже не затрагивая проект UI. Но, чтобы вам не стало скучно, мы сменим курс и начнем использовать MVC Framework в полную силу. Мы будем добавлять новые функции в модель и хранилище по мере необходимости.

В этом разделе мы создадим контроллер и метод действия, который будет отображать информацию о товарах, находящихся в хранилище. На данный момент у нас есть данные только в имитированном хранилище, но мы решим этот вопрос позже. Мы также проведем начальные настройки конфигурации маршрутизации, чтобы MVC было известно, как отображать запросы к приложению в контроллер, который мы собираемся создать.

Добавляем контроллер

Кликните правой кнопкой мыши папку Controllers в проекте SportsStore.WebUI и выберите Add - Controller в контекстном меню. Назначьте контроллеру имя ProductController и убедитесь, что опция Template содержит Empty controller. Когда Visual Studio открывает файл для редактирования, вы можете удалить метод действия по умолчанию, который был добавлен автоматически, и ваш файл будет выглядеть как в листинге 7-6.

Листинг 7-6: Начальное определение ProductController

using System;

using System.Collections.Generic; using System.Linq;

using System.Web; using System.Web.Mvc;

using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities;

namespace SportsStore.WebUI.Controllers

{

public class ProductController : Controller

{

private IProductRepository repository;

public ProductController(IProductRepository productRepository)

{

this.repository = productRepository;

}

}

}

Удалив метод действия Index, мы добавляем конструктор, который принимает параметр IProductRepository. Это позволит Ninject внедрять зависимость для хранилища товаров, когда он будет создавать экземпляр класса контроллера. Мы также импортировали пространства имен SportsStore.Domain, так что мы можем обращаться к хранилищу и классам моделей, не указывая их имен.

Далее мы добавляем метод действия под названием List, который будет визуализировать представление, показывающее полный список товаров, как показано в листинге 7-7.

Листинг 7-7: Добавляем метод действия

using System;

using System.Collections.Generic; using System.Linq;

using System.Web;

161

using System.Web.Mvc;

using SportsStore.Domain.Abstract; using SportsStore.Domain.Entities;

namespace SportsStore.WebUI.Controllers

{

public class ProductController : Controller

{

private IProductRepository repository;

public ProductController(IProductRepository productRepository)

{

this.repository = productRepository;

}

public ViewResult List()

{

return View(repository.Products);

}

}

}

Такой вызов метода View (без указания имени представления) сообщает платформе визуализировать представление по умолчанию для данного метода действия. Передавая список List объектов Product в метод View, мы предоставляем платформе данные для заполнения объекта Model в строго типизированном представлении.

Добавляем представление

Теперь нам нужно добавить представление по умолчанию для метода действия List. Щелкните правой кнопкой мыши метод List в редакторе кода и выберите Add - View в контекстном меню. Присвойте представлению имя List и отметьте флажком опцию, которая создает строго типизированные представления, как показано на рисунке 7-5.

Рисунок 7-5: Добавляем представление List

162

Вполе Model class введите IEnumerable<SportsStore.Domain.Entities.Product>. Вам придется напечатать это название; оно не будет доступно из раскрывающегося списка, который не включает перечисления доменных объектов.

Вдальнейшем мы будем использовать стандартный макет Razor, который включен в шаблон проекта Basic, чтобы наши представления выглядели единообразно. Отметьте флажком опцию Use a layout, но оставьте текстовое поле пустым, как показано на рисунке. Нажмите кнопку Add, чтобы

создать представление.

Визуализируем данные представления

Зная, что модель в представлении является IEnumerable<Product>, мы можем создать список с помощью цикла foreach в Razor, как показано в листинге 7-8.

Листинг 7-8: Представление List.cshtml

@model IEnumerable<SportsStore.Domain.Entities.Product>

@{

ViewBag.Title = "Products";

}

@foreach (var p in Model)

{

<div class="item"> <h3>@p.Name</h3> @p.Description <h4>@p.Price.ToString("c")</h4>

</div>

}

Мы также изменили заголовок страницы. Обратите внимание, что нам не нужно использовать элементы Razor text или @: для отображения данных представления, потому что каждая строка в теле кода либо является директивой Razor, либо начинается с HTML-элемента.

Совет

Обратите внимание, что мы преобразовали свойство Price в строку с помощью метода ToString("с"), который отображает числовые значения как валюту в

соответствии с настройками культуры, которые действуют на вашем сервере. Например, если сервер настроен как en-US, то (1002,3).ToString ("с") вернет $1,002.30, но если сервер настроен как en-GB, тот же метод вернет £1,002,30. Вы

можете изменить настройку культуры для вашего сервера, добавив в узел

<system.web> файла Web.config следующую секцию: <globalization

culture="en-GB" uiCulture="en-GB" />.

Настраиваем роут по умолчанию

Сейчас нам достаточно сообщить платформе MVC, что запросы, поступающие в корень сайта (http://mysite/), нужно отображать в метод действия List класса ProductController. Для этого мы редактируем оператор в методе RegisterRoutes в файле App_Start/RouteConfig.cs, как показано в листинге 7-9.

163

Листинг 7-9: Добавляем роут по умолчанию

using System;

using System.Collections.Generic; using System.Linq;

using System.Web; using System.Web.Mvc;

using System.Web.Routing;

namespace SportsStore.WebUI

{

public class RouteConfig

{

public static void RegisterRoutes(RouteCollection routes)

{

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute( name: "Default",

url: "{controller}/{action}/{id}", defaults: new

{

controller = "Product", action = "List",

id = UrlParameter.Optional

}

);

}

}

}

Измените Home на Product и Index на List, как показано в листинге. Мы подробно опишем возможности маршрутизации в ASP.NET в главе 13. На данный момент достаточно знать, что это изменение будет направлять запросы к URL по умолчанию в метод действия, который мы определили.

Совет

Обратите внимание, что в листинге 7-9 мы установили контроллеру значение Product, а не ProductController, что является именем класса. Это часть схемы

именования ASP.NET MVC, в которой имена классов контроллеров всегда заканчиваются на Controller, и при обращении к классу эта часть имени

опускается.

Запускаем приложение

Все базовые составляющие приложения готовы. У нас есть контроллер с методом действия, который вызывается при запросе URL по умолчанию. Этот метод действия полагается на имитированную реализацию нашего интерфейса хранилища, которая генерирует простые тестовые данные. Тестовые данные передаются в представление, которое мы связали с методом действия, и оно создает простой список с информацией для каждого товара. Если вы запустите приложение, то увидите результат, показанный на рисунке 7-6.

164

Рисунок 7-6: Просматриваем базовую функциональность приложения

Это типичный шаблон разработки для платформы ASP.NET MVC. Мы отводим довольно много времени на настройку, но затем разработка базовой функциональности приложения происходит очень быстро.

Подготовка базы данных

Мы уже можем отображать простые представления, содержащие информацию о товарах, но мы попрежнему выводим тестовые данные, которые возвращает наше имитированное хранилище IProductRepository. Прежде чем мы сможем реализовать реальное хранилище, нам нужно создать базу данных и заполнить ее данными.

В качестве базы данных мы будем использовать SQL Server и обращаться к ней с помощью Entity Framework (EF), которая является ORM-платформой .NET. Платформа ORM позволяет нам работать с таблицами, столбцами и строками в реляционной базе данных с помощью обычных объектов C#. Мы уже упоминали в главе 6, что LINQ может работать с различными источниками данных, одним из которых является Entity Framework. Вы вскоре увидите, как она упрощает работу.

Это еще один источник, который предоставляет нам широкий спектр инструментов и технологий. Здесь доступны не только различные реляционные базы данных, но вы также можете работать с хранилищами объектов, архивами документов и некоторыми малоизвестными альтернативами. Существует много платформ ORM, в которых применяются немного разные подходы и которые будут лучше подходить для тех или иных проектов.

Мы используем Entity Framework по нескольким причинам. Во-первых, ее легко настроить и начать работу. Во-вторых, мы хотим использовать LINQ, а у нее первоклассная интеграция с LINQ. Третья причина заключается в том, что Entity Framework на самом деле очень хорошая платформа. Более ранние версии были немного неточными, но современные версии многофункциональны и отлично работают.

165

Создаем базу данных

Одно из приятных дополнений к Visual Studio 2012 и SQL Server 2012 - версия LocalDB. Это безадминистративная реализация функций ядра SQL Server, предназначенных только для разработчиков. Используя эту версию, мы можем пропустить процесс настройки базы данных, пока мы создаем проект, а затем развернуть приложение на полном экземпляре SQL Server. Большинство приложений MVC развертываются на удаленных платформах, которые находятся в ведении профессиональных администраторов. Версия LocalDB означает, что конфигурацию базы данных можно оставить администраторам баз данных, а разработчики смогут заняться кодированием. Версия LocalDB автоматически устанавливается вместе с Visual Studio Express 2012 for Web, но при желании вы можете скачать ее непосредственно с сайта www.microsoft.com/SQLServer.

Для начала мы создадим соединение с базой данных в Visual Studio. Откройте Database Explorer в меню View и кликните по кнопке Connect to Database (которая выглядит как кабель питания с зеленым плюсом).

Вы увидите диалоговое окно Add Connection. Присвойте серверу имя (localdb)\v11.0 - это специальное имя, которое означает, что вы хотите использовать версию LocalDB. Отметьте флажком опцию Use Windows Authentication и назовите базу данных SportsStore, как показано на рисунке

7-7.

Рисунок 7-7: Настраиваем базу данных SportsStore

166

Нажмите ОК, и вам будет предложено создать новую базу данных. Нажмите Yes, и в окне Database Explorer появится новая запись. Разверните этот пункт, чтобы увидеть различные аспекты новой базы данных, как показано на рисунке 7-8.

Рисунок 7-8: База данных LocalDB в окне Database Explorer

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

Определяем схему базы данных

Внашей базе данных нам нужна только одна таблица, в которой мы будем хранить объекты Product.

Вокне Database Explorer разверните базу данных, которую вы только что создали, и кликните правой кнопкой мыши по пункту Tables. Выберите из меню Add - New Table, как показано на рисунке 7-9.

Рисунок 7-9: Добавляем новую таблицу

167

Вы увидите конструктор для создания новой таблицы. Вы можете создавать новые таблицы базы данных с помощью визуальной части конструктора, но мы будем использовать окно T-SQL, потому что это более краткий и точный способ описать необходимую спецификацию таблицы. Введите SQLоператор, показанный в листинге 7-10, и нажмите кнопку Update в верхнем левом углу окна конструктора.

Листинг 7-10: SQL-оператор для создания таблицы в базе данных SportsStore

CREATE TABLE Products

(

[ProductID] INT NOT NULL PRIMARY KEY IDENTITY, [Name] NVARCHAR(100) NOT NULL,

[Description] NVARCHAR(500) NOT NULL, [Category] NVARCHAR(50) NOT NULL, [Price] DECIMAL(16, 2) NOT NULL

)

Этот оператор создает таблицу под названием Products, которая содержит столбцы для различных свойств, которые мы определили в классе модели Product ранее в этой главе.

Совет

Настройка свойства IDENTITY для столбца ProductID означает, что SQL Server

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

Когда вы нажмете кнопку Update, вам будет показана информация об эффекте оператора, как показано на рисунке 7-10.

Рисунок 7-10: Информация об эффекте SQL-оператора

168

Нажмите кнопку Update Database, чтобы выполнить SQL и создать таблицу Products в базе данных.Вы сможете увидеть эффект обновления, если нажмете на кнопку Refresh в окне Database Explorer. Раздел Tables показывает новую таблицу Product и информацию о каждой строке.

Совет

После обновления базы данных вы можете закрыть окно dbo.Products. Visual Studio предложит сохранить SQL-скрипт, который вы использовали для создания базы данных. Вам не нужно его сохранять в этой главе, но это может быть полезно сделать в реальных проектах, если вам понадобится настраивать несколько баз данных.

Добавляем данные в базу данных

Мы добавим в базу некоторые данные вручную, чтобы было с чем работать до тех пор, пока не добавим средства администрирования каталога в главе 10.

В окне Database Explorer разверните пункт Tables базы данных SportsStore кликните правой кнопкой мыши таблицу Products и выберите Show - Table Data. Введите данные, показанные на рисунке 7-11. Переходить на другую строку можно с помощью клавиши Tab. Нажимая Tab в конце каждой строки, вы перейдете к следующей строке и обновите данные в базе.

Внимание

Вы должны оставить столбец ProductID пустым. Это столбец идентификации, для которого SQL Server создаст уникальное значение, когда вы перейдете на другую строку.

Рисунок 7-11: Добавляем данные в таблицу Products

Создаем контекст Entity Framework

Последние версии Entity Framework включает отличную возможность под названием code-first. Смысл том, что мы можем определить классы в нашей модели, а затем сгенерировать базы данных из этих классов.

169

Это очень удобно для проектов, которые разрабатываются с нуля. Но так как таких проектов очень мало, мы продемонстрируем вам версию code-first, в которой будем связывать классы моделей с существующей базой данных. Для начала мы добавим версию Entity Framework 5.0 в проект

SportsStore.Domain. Кликните правой кнопкой мыши пункт References в Solution Explorer, а

затем выберите пункт Manage NuGet Packages в контекстном меню. Введите entity в поле поиска и выберите поиск пакета EntityFramework, как показано на рисунке 7-12, а затем нажмите кнопку Install. Visual Studio скачает и установит последнюю версию пакета Entity Framework.

Рисунок 7-12: Добавляем библиотечный пакет EntityFramework

Следующим шагом будет создание класса контекста, который будет связывать нашу простую модель с базой данных. Создайте новую папку под названием Concrete и добавьте в нее класс под названием EFDbContext. Отредактируйте содержимое файла так, как показано в листинге 7-11.

Листинг 7-11: Класс EFDbContext

using SportsStore.Domain.Entities; using System.Data.Entity;

namespace SportsStore.Domain.Concrete

{

public class EFDbContext : DbContext

{

public DbSet<Product> Products { get; set; }

}

}

Чтобы воспользоваться возможностью code-first, мы должны создать класс, который наследует от System.Data.Entity.DbContext. Этот класс будет автоматически определять свойство для каждой таблицы в базе данных, с которой мы будем работать.

Имя свойства указывает таблицу, а параметр типа результата DbSet конкретизирует модель, которую должна использовать Entity Framework для репрезентации строк в данной таблице. В нашем случае

170

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]