Создание контроллера и представлений

Данное руководство устарело. Актуальное руководство: Руководство по ASP.NET Core

Последнее обновление: 31.10.2015

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

У вас будет создан следующий контроллер:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace BookStore.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }
    }
}

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using BookStore.Models;
 
namespace BookStore.Controllers
{
    public class HomeController : Controller
    {
        // создаем контекст данных
        BookContext db = new BookContext();
 
        public ActionResult Index()
        {
            // получаем из бд все объекты Book
            IEnumerable<Book> books = db.Books;
            // передаем все полученный объекты в динамическое свойство Books в ViewBag
            ViewBag.Books = books;
            // возвращаем представление
            return View();
        }
    }
}

Прежде всего, обратите внимание, что, так как у нас модели находятся в другом пространстве имен, хотя и в одном проекте, то мы его должны импортировать. Затем мы создаем контекст данных. Используя свойство Books, мы получаем из базы данных список объектов Book.

Далее мы создаем объект Books в объекте ViewBag и присваиваем ему этот список. Объект ViewBag является таким объектом, который передается в представление. И мы можем определить в этом объекте любую переменную и передать ей некоторое значение, а затем в представлении извлечь это значение.

А теперь создадим само представление. Наведем курсор на метод Index и нажмем правой кнопкой мыши. Нам отобразится меню, в котором выберем Add View....

Затем нам откроется окно добавления представления, где нам будет предложено выбрать имя представления и еще ряд параметров. Поскольку у нас еще нет мастер-страниц в проекте, снимем галочку с флажка Use a layout or masterpage: и нажмем Add.

Позже в соответствующей главе мы подробнее поговорим про опции создания и вообще про представления. А пока Visual Studio автоматически откроет созданное представление Index.cshtml. По сути оно пусто и содержит минимальный код разметки на языке html. Изменим его следующим образом:

@{
    Layout = null;
}
 
<!DOCTYPE html>
 
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Книжный магазин</title>
</head>
<body>
    <div>
        <h3>Распродажа книг</h3>
        <table>
            <tr><td><p>Название книги</p></td>
                <td><p>Автор</p></td>
                <td><p>Цена</p></td><td></td>
            </tr>
            @foreach (var b in ViewBag.Books)
            {
            <tr>
                <td><p>@b.Name</p></td>
                <td><p>@b.Author</p></td>
                <td><p>@b.Price</p></td>
                <td><p><a href="/Home/Buy/@b.Id">Купить</a></p></td>
            </tr>
            }
        </table>
    </div>
</body>
</html>

Здесь мы создаем таблицу, в которой будут располагаться наши данные о книгах. Особый интерес представляет конструкция @foreach (var c in ViewBag.Books). Эта конструкция использует синтаксис движка представления Razor (а именно его мы выбрали при создании представления). Подробнее мы погорим о движке Razor в отдельной главе, а пока вам надо знать, что после символа @ согласно синтаксису мы можем использовать выражения кода на языке C#.

В цикле мы пробегаемся по элементам в объекте ViewBag.Books, который мы ранее создали в методе контроллера. И затем получаем свойства каждого элемента и помещаем его в ячейку таблицы.

Ссылка в конце - <a href="/Home/Buy/@b.Id">Купить</a> будет означать адрес, по которому будет размещаться форма оформления покупки выбранной книги.

Основы маршрутизации

Чтобы вызвать контроллер HomeController или отправить ему запрос, нам надо указать в строке запроса его имя - Home. Кроме того, после имени контроллера нам надо через слеш указать действие или метод контроллера, к которому отправляется запрос. По умолчанию при запуске проекта или при обращении к сайту система mvc будет вызывать действие Index контроллера HomeController, если мы не укажем иной маршрут по умолчанию в параметрах маршрутизации. Путь /Home/Buy/@b.Id означает, что мы будем обращаться к методу Buy контроллера HomeController. Но перед тем как создать этот метод, наполним приложение данными.

Данные для моделей по умолчанию

Мы можем уже сейчас запустить наше приложение, однако кроме строки с заголовками в таблице мы ничего не увидим, потому что у нас же еще нет данных. Здесь мы могли поступить двумя способами: либо добавить в базу данных mssql некоторые данные, либо инициализировать начальные данные для моделей в коде. Выберем второй вариант. Для этого в папку Models добавим новый класс BookDbInitializer и добавим в него следующий код:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
 
namespace BookStore.Models
{
    public class BookDbInitializer : DropCreateDatabaseAlways<BookContext>
    {
        protected override void Seed(BookContext db)
        {
            db.Books.Add(new Book { Name = "Война и мир", Author = "Л. Толстой", Price = 220 });
            db.Books.Add(new Book { Name = "Отцы и дети", Author = "И. Тургенев", Price = 180 });
            db.Books.Add(new Book { Name = "Чайка", Author = "А. Чехов", Price = 150 });
 
            base.Seed(db);
        }
    }
}

С помощью данного класса мы создаем три объекта Book и добавляем их в базу данных. Чтобы этот класс заработал, нам надо не только его объявить, но и запустить. Все начальные настройки и конфигурации у нас хранятся в файле Global.asax. Откроем его и добавим в него в метод Application_Start, который отрабатывает при старте приложения, следующую строчку:

Database.SetInitializer(new BookDbInitializer());

Ну и конечно, импортируем в файле Global.asax пространства имен [имя_проекта].Models и System.Data.Entity, иначе класс BookDbInitializer будет недоступен.

Все, теперь, если мы запустим приложение, то увидим, что в таблице содержатся ранее определенные нами данные:

И если мы откроем папку проекта и зайдем в ней в каталог App_Data, то найдем только что созданную базу данных Bookstore.mdf, которая и будет хранить таблицы с данными.

Да, наша таблица выглядит немного неказисто, не мешало бы применить к ней стили, но не сейчас. Сейчас нам надо создать метод Buy, который будет отвечать за обработку ввода пользователя при оформлении покупки. Добавим в контроллер HomeController следующие два метода:

[HttpGet]
public ActionResult Buy(int id)
{
    ViewBag.BookId = id;
    return View();
}
[HttpPost]
public string Buy(Purchase purchase)
{
    purchase.Date = DateTime.Now;
    // добавляем информацию о покупке в базу данных
    db.Purchases.Add(purchase);
    // сохраняем в бд все изменения
    db.SaveChanges();
    return "Спасибо," + purchase.Person + ", за покупку!";
}

По сути здесь мы определили одно действие Buy, однако в одном случае оно выполняется при получении запроса GET, а во втором случае - при получении запроса POST, что мы и определили с помощью атрибутов [HttpGet] и [HttpPost]. Метод public ActionResult Buy(int id) очень прост - он просто принимает id выбранной книги и возвращает для нее соответствующее представление.

Метод public string Buy(Purchase purchase) выглядит несколько сложнее. Он принимает переданную ему в запросе POST модель purchase и добавляет ее в базу данных. В конце мы возвращаем строку сообщения.

И в конце добавим представление Buy. Для этого нажмем на метод public ActionResult Buy(int id) правой кнопкой и добавим в проект новое представление. Изменим код нового представления следующим образом:

@{
    Layout = null;
}
 
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Покупка</title>
</head>
<body>
    <div>
        <h3>Форма оформления покупки</h3>
        <form method="post">
            <input type="hidden" value="@ViewBag.BookId" name="BookId" />
            <table>
                <tr><td><p>Введите свое имя </p></td>
                    <td><input type="text" name="Person" /> </td></tr>
                <tr><td><p>Введите адрес :</p></td><td>
                   <input type="text" name="Address" /> </td></tr>
                <tr><td><input type="submit" value="Отправить" /> </td><td></td></tr>
            </table>
        </form>
    </div>
</body>
</html>

Здесь мы создали форму ввода данных. При переходе по ссылке "/Home/Buy/2" контроллер будет получать запрос к действию Buy. И так как такой запрос представляет тип GET, пользователю будет возвращаться форма. После заполнения формы и нажатия на кнопку форма будет оправляться запросом POST, так как мы его определили в строке <form method="post" action="">. Контроллер снова будет получать запрос к методу Buy, только теперь будет выбираться для обработки запроса метод public string Buy(Purchase purchase).

Каким образом система MVC угадывает, что мы передали с запросом post информацию о модели? Обратите внимание на поля ввода <input type="text" name="Person" /> и <input type="text" name="Address" />. Их свойства name соответствуют именам свойств модели Purchase. При нажатии кнопки и отправки запроса передаются значения этих полей. Система MVC, используя соглашения по умолчанию, считает эти значения значениями соответствующих свойств модели.

Теперь первое мини-тренировочное приложение готово, и мы можем его запустить. Перейдите на страницу оформления заказа, заполните поля и нажмите кнопку "Отправить".

После этого ваша заявка на покупку книги попадет в базу данных, а в браузере отобразится соответствующее уведомление.

А теперь добавим к нашему сайту элементы стилизации в виде стилей css, а также мастер-страницы, которые позволяют придать всем страницам сайта единообразный вид.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850