ASP.NET MVC Урок 1

Автор: | 12.02.2017

Создание проекта

Когда вы впервые создаете новый проект MVC Framework, у вас есть на выбор две базовых отправных точки: шаблон Empty (Пустой) и шаблон MVC. Эти имена несколько обманчивы, так как добавить базовые папки и сборки, требуемые для MVC Framework, можно в любой проект, отметив флажок MVC в разделе Add folders and core references for (Добавить папки и основные ссылки для) диалогового окна New ASP.NET Project (Новый проект ASP.NET), как показано на рисунке ниже. В случае выбора шаблона MVC этот флажок отмечается автоматически.

Реальное отличие связано с дополнительным содержимым, которое шаблон MVC добавляет в новые проекты. Оно предоставляет готовую отправную точку, включающую стандартные контроллеры и представления, конфигурацию безопасности, ряд популярных пакетов JavaScript и CSS (таких как jQuery и Bootstrap), а также компоновку — которая применяет библиотеку Bootstrap для построения темы, оформляющей пользовательский интерфейс приложения.

Вариант Empty проекта содержит только базовые ссылки, требуемые для MVC Framework, и базовую структуру папок. Шаблон MVC добавляет довольно много содержимого, и разницу можно видеть на рисунке ниже, где показано содержимое двух созданных проектов. Проект в левой части создан с применена шаблона Empty при отмеченном флажке MVC. Проект в правой части создан с использованием шаблона MVC, и чтобы продемонстрировать все файлы в нем, пришлось открывать разные папки в окне Solution Explorer, т.к. список файлов оказался бы слишком длинным.

Разница между пустым и MVC шаблоном в ASP.NET

Разница между пустым и MVC шаблоном в ASP.NET

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

Среда Visual Studio собирает проект, созданный с помощью шаблона MVC, используя пакеты NuGet, а это значит, что вы можете просмотреть, какие пакеты применяются, выбрав пункт Manage NuGet Packages for Solution (Управление пакетами NuGet для решения) в меню Tools => Library Package Manager (Сервис => Диспетчер библиотечных пакетов). Это также означает возможность добавления тех же самых пакетов в любой проект, в том числе и созданный с использованием шаблона Empty.

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

 

Сводка по элементам проектов MVC

/App_Data
В эту папку помещаются закрытые данные, такие как XML-файлы или базы данных, если используется SQL Server Express, SQLite или другие хранилища на основе файлов

/App_Start
Эта папка содержит ряд основных настроек конфигурации для проекта, в том числе определение маршрутов и фильтров, а также пакетов содержимого

Маршруты и фильтры рассматриваются позже

/Areas
Области — это способ разделения крупного приложения на меньшие части

/bin
Сюда помещается скомпилированная сборка приложения MVC вместе со всеми ссылаемыми сборками, находящимися не в GAC

Чтобы увидеть папку bin в окне Solution Explorer, понадобится щелкнуть на кнопке Show All Files (Показать все файлы). Поскольку все файлы в этой папке являются двоичными и генерируются в результате компиляции, обычно они не хранятся в системе управления исходным кодом

/Content
Сюда помещается статическое содержимое, такое как CSS-файлы и изображения

Это является необязательным соглашением. Статическое содержимое можно хранить в любом подходящем месте

/Controllers
Сюда помещаются классы контроллеров

Это является соглашением. Классы контроллеров могут размещаться где угодно, поскольку они компилируются в ту же самую сборку

/Models
Сюда помещаются классы моделей представлений и моделей предметной области, хотя все кроме простейших приложений выигрывают от определения модели предметной области в отдельном проекте

Это является соглашением. Классы моделей могут быть определены где угодно в текущем проекте или вообще вынесены в отдельный проект

/Scripts
Эта папка предназначена для хранения библиотек JavaScript, используемых в приложении. По умолчанию Visual Studio добавляет библиотеки jQuery и несколько других популярных JavaScript-библиотек

Это является соглашением. Файлы сценариев могут находиться в любом месте, т.к. в действительности они представляют собой просто другой тип статического содержимого

/Views
В этой папке хранятся представления и частичные представления, обычно сгруппированные вместе в папках с именами контроллеров, с которыми они связаны

/Views/Shared
В этой папке хранятся компоновки и представления, не являющиеся специфичными для какого-либо контроллера

/Views/Web.config
Это конфигурационный файл. В нем содержится конфигурационная информация, которая обеспечивает обработку представлений с помощью ASP.NET и предотвращает их обслуживание веб-сервером IIS, а также пространства имен, по умолчанию импортируемые в представления

Файл /Views/Web.config предотвращает обслуживание веб-сервером IIS содержимого этих папок. Представления должны визуализироваться через методы действий

/Global.asax
Это глобальный класс приложения ASP.NET. В его файле отделенного кода (Global.asax.cs) регистрируется конфигурация маршрутов, а также предоставляется любой код, который должен выполняться при запуске или завершении приложения либо в случае возникновения необработанного исключения

В приложении MVC файл Global.asax играет ту же самую роль, что и в приложении Web Forms

/Web.config
Конфигурационный файл для приложения

В приложении MVC файл Web.config играет ту же самую роль, что и в приложении Web Forms

Соглашения в MVC

В проекте MVC применяются два вида соглашений. Соглашения первого вида — это просто предположения о том, как может выглядеть структура проекта.

Например, общепринято размещать файлы JavaScript в папке Scripts. Здесь их рассчитывают обнаружить другие разработчики, использующие MVC, и сюда будут устанавливаться пакеты NuGet. Однако вы вольны переименовать папку Scripts или вообще удалить ее — разместив файлы сценариев где-то в другом месте. Это не помешает инфраструктуре MVC Framework запустить ваше приложение при условии, что элементы <script> внутри представлений ссылаются на местоположение, в котором находятся файлы сценариев.

Соглашения второго вида произрастают из принципа соглашения по конфигурации (convention over configuration) или соглашения над конфигурацией, если делать акцент на преимуществе соглашения перед конфигурацией, который был одним из главных аспектов, обеспечивших популярность платформе Ruby on Rails. Соглашение по конфигурации означает, что вы не должны явно конфигурировать, к примеру, ассоциации между контроллерами и их представлениями. Нужно просто следовать определенному соглашению об именовании для файлов — и все будет работать. При соглашении такого рода снижается гибкость в изменении структуры проекта. В последующих разделах объясняются соглашения, которые используются вместо конфигурации.

Следование соглашениям для классов контроллеров

Классы контроллеров должны иметь имена, заканчивающиеся на Controller, например, ProductController, ShopController. При ссылке на контроллер где-либо в проекте, скажем, при вызове вспомогательного метода HTML, указывается первая часть имени (такая как Product), а инфраструктура MVC Framework автоматически добавляет к этому имени слово Controller и начинает поиск класса контроллера.

Это поведение можно изменить, создав собственную реализацию интерфейса IControllerFactory.

Следование соглашениям для представлений

Представления и частичные представления располагаются в папке:

/Views/ИмяКонтроллера

Например, представление, ассоциированное с классом ProductController, находится в папке /Views/Product. Обратите внимание, что часть Controller имени класса в имени папки внутри Views не указывается, т.е. используется папка /Views/Product, а не /Views/ProductController. Поначалу такой подход может показаться нелогичным, но это очень скоро войдет в привычку.

Инфраструктура MVC Framework ожидает, что стандартное представление для метода действия должно иметь имя этого метода. Например, представление, ассоциированное с методом действия List(), должно называться List.cshtml. Таким образом, ожидается, что для метода действия List() в классе ProductController стандартным представлением будет /Views/Product/List.cshtml.

Стандартное представление используется при возвращении результата вызова метода View() в методе действия, примерно так:

return View();

Можно указать имя другого представления:

 return View(«MyOtherView»);

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

Следование соглашениям для компоновок

Соглашение об именовании для компоновок предусматривает добавление к имени файла символа подчеркивания _, а сами файлы компоновки помещаются в папку /Views/Shared. Среда Visual Studio создает компоновку по имени Layout.cshtml для всех шаблонов проектов кроме Empty. Эта компоновка по умолчанию применяется ко всем стандартным представлениям через файл /Views/_ViewStart.cshtml. Если вы не хотите, чтобы стандартная компоновка применялась к представлениям, можете изменить настройки в _ViewStart.cshtml (либо вообще удалить этот файл), указав другую компоновку в представлении, например:

@{ Layout = "~/Views/Shared/MyLayout.cshtml"; }

Или же можно отключить компоновку для заданного представления:

@{ Layout = null; }

Создание простого проекта ASP.NET MVC

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

Подготовка Visual Studio

Среда Visual Studio Express содержит все средства, необходимые для создания, тестирования и развертывания приложения MVC Framework, но некоторые из этих средств скрыты до тех пор, пока вы их не запросите. Чтобы включить все средства, выберите пункт Expert Settings (Развернутые настройки) в меню Tools —> Settings (Сервис —> Настройки) среды Visual Studio.

По ряду причин в Microsoft решили, что все названия высокоуровневых меню среды Visual Studio должны быть представлены заглавными буквами, т.е. на самом деле упомянутое меню Tools в интерфейсе среды выглядит как TOOLS. Это так, на заметку.

Новый проект ASP.NET MVC

Мы собираемся начать с создания нового проекта MVC Framework в среде Visual Studio. Выберите в меню File(Файл) пункт New Project (Проект).

Создание нового проекта MVC

Создание нового проекта MVC

Далее в открывшемся диалоговом окне вам необходимо указать имя проекта PartyInvite (Приглашение на вечеринку).

Создаем новое приложение MVC и задаем ему имя

Создаем новое приложение MVC и задаем ему имя

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

Как создать проект MVC в ASP.NET

Как создать проект MVC в ASP.NET

Шаблоны проектов MVC создают проекты с разными отправными точками и конфигурациями для таких средств, как аутентификация, навигация и визуальные темы. Мы собираемся придерживаться максимальной простоты. Поэтому мы выбрали Empty (Пустой) тип проекта и для автоматического создания структуры проекта отметили флажок MVC в разделе Add folders and core references for (Добавить папки и основные ссылки для), как показано на рисунке выше. Это приведет к созданию базового проекта MVC с минимальным заранее определенным содержимым, который будет служить отправной точкой для всех примеров, рассматриваемых далее.

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

После того как среда Visual Studio создаст проект, в окне Solution Explorer отобразится набор файлов и папок. Это стандартная структура для нового проекта MVC и вы уже узнали, для чего предназначен каждый файл и каждая папка, созданные Visual Studio.

Теперь можно попробовать запустить приложение, выбрав в меню Debug (Отладка) пункт Start Debugging (Запустить отладку); если появится запрос на включение отладки, просто щелкните на кнопке ОК. Результат показан на рисунке ниже. Поскольку мы начали с шаблона проекта Empty, приложение не содержит ничего, что могло бы быть выполнено, поэтому сервер генерирует ошибку 404 Not Found (не найдено):

 

Первый запуск пустого приложения ASP.NET MVC

Первый запуск пустого приложения ASP.NET MVC

Добавление первого контроллера

В архитектуре MVC входящие запросы обрабатываются контроллерами. В ASP.NET MVC контроллеры — это просто классы C# (обычно унаследованные от System.Web.Mvc.Controller, встроенного в инфраструктуру базового класса контроллера). Каждый открытый метод в контроллере называется методом действия а это значит, что его можно вызвать из веб-среды через некоторый URL-адрес для выполнения действия. В соответствии с соглашением MVC контроллеры помещаются в папку Controllers, автоматически создаваемую Visual Studio при настройке проекта.

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

Чтобы добавить контроллер в проект, щелкните правой кнопкой мыши на папке Controllers в окне Solution Explorer среды Visual Studio и выберите в контекстном меню пункт Add (Добавить), а затем Controller (Контроллер), как продемонстрировано на рисунке ниже:

Добавление первого контроллера в MVC проект ASP.NET

Добавление первого контроллера в MVC проект ASP.NETКогда откроется диалоговое окно Add Scaffold (Добавление шаблона), выберите вариант MVC 5 Controller — Empty (Контроллер MVC 5 — Пустой), как показано на рисунке ниже, и щелкните на кнопке Add (Добавить).

Окно добавления контроллера в MVC проект

Окно добавления контроллера в MVC проект

Откроется диалоговое окно Add Controller (Добавление контроллера). Укажите HomeController в качестве имени контроллера и щелкните на кнопке Add (Добавить). С этим именем связано несколько соглашений: имена, выбираемые для контроллеров, должны отражать их назначение, стандартный контроллер называется Home и имена контроллеров имеют суффикс Controller.

Если вы применяли для создания приложений MVC ранние версии Visual Studio, то заметите, что процесс слегка отличается. В Microsoft изменили способ, которым Visual Studio может заполнять проект заранее сконфигурированными классами и другими элементами.

Итак, среда Visual Studio создаст в папке Controllers новый файл C# по имени HomeController.cs и откроет его для редактирования. В примере ниже приведено стандартное содержимое, которое Visual Studio помещает в этот файл класса. Как видите, класс имеет имя DefaultController и является производным от класса Controller, который находится в пространстве имен System.Web.Mvc.

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

namespace WebApplication7.Controllers
{
    public class HomeController : Controller
    {
        // GET: Default
        public ActionResult Index()
        {
            return View();
        }
    }
}

Удобный способ приступить к знакомству с MVC предусматривает внесение в класс контроллера пары простых изменений. Отредактируйте код в файле HomeController.cs так, чтобы он приобрел вид, показанный в примере ниже:

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

namespace WebApplication7.Controllers
{
    public class HomeController : Controller
    {
        // GET: Default
        public String Index()
        {
            return "Hello, world!";
            
        }
    }
}

Изменения не приводят к каким-то особо впечатляющим результатам, но их вполне достаточно для хорошей демонстрации. Метод действия по имени Index() изменен так, что теперь он возвращает строку «Hello, World». Снова запустите проект, выбрав пункт Start Debugging из меню Debug в Visual Studio. Браузер отобразит результат выполнения метода действия Index(), как показано на рисунке ниже:

Первый MVC проект Привет мир в ASP.NET

Первый MVC проект Привет мир в ASP.NET

 

Примечание: Не забывайте останавливать проект после запуска. Для остановки проекта используйте кнопку Stop

Остановить отладку MVC приложения в ASP.NET

Остановить отладку MVC приложения в ASP.NET

Если вы не остановите отладку то вы не сможете вносить изменения в свой проект.

Изменение кода во время отладки MVC проекта недопустимо в ASP.NET

Изменение кода во время отладки MVC проекта недопустимо в ASP.NET

Обратите внимание, что среда Visual Studio направляет браузер на порт 45361. В URL-адресе, который будет запрашивать ваш браузер, почти наверняка будет присутствовать другой номер порта, т.к. Visual Studio выделяет произвольный порт при создании проекта. Если вы заглянете в область уведомлений панели задач Windows, то найдете там значок для IIS Express. Этот значок представляет усеченную версию полного сервера приложений IIS, которая входит в состав Visual Studio и используется для доставки содержимого и служб ASP.NET во время разработки.

Понятие маршрутов

Кроме моделей, представлений и контроллеров приложения MVC используют систему маршрутизации ASP.NET, которая определяет, как URL отображаются на контроллеры и действия. Когда среда Visual Studio создает проект MVC, она добавляет ряд стандартных маршрутов, выступающих в качестве начальных. Можно запросить любой из следующих URL, и они будут направлены на действие Index контроллера:

/
/Home
/Home/Index

Таким образом, когда браузер запрашивает http://ваш-сайт/ или http://ваш_сайт/Home, он получает вывод из метода Index() контроллера HomeController. Можете опробовать это самостоятельно, изменив URL в браузере. В настоящий момент он будет выглядеть как http://localhost:45361/, при этом часть, представляющая порт, может быть другой. Если вы добавите к URL порцию /Home или /Home/Index и нажмете клавишу <Enter>, то получите от приложения MVC тот же самый результат — строку «Hello, world».

Это хороший пример получения выгоды от соблюдения соглашений MVC. В данном случае соглашение заключается в том, что контроллер назван HomeController, и он будет служить стартовой точкой нашего приложения MVC. При создании стандартных маршрутов для нового проекта среда Visual Studio исходит из предположения, что мы будем следовать этому соглашению. И поскольку мы действительно соблюдаем соглашение, мы автоматически получаем поддержку всех URL из приведенного выше списка.

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

Визуализация веб-страниц

Выводом предыдущего примера была не HTML-разметка, а просто строка «Hello World». Чтобы сгенерировать HTML-ответ на запрос браузера, понадобится создать представление.

Создание и визуализация представления

Прежде всего, необходимо вернуть метод действия Index() в исходное состояние, как показано в примере ниже:

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

namespace WebApplication7.Controllers
{
    public class HomeController : Controller
    {
        // GET: Default
        public ActionResult Index()
        {
            return View();
        }
    }
}

Возвращая объект ViewResult из метода действия, мы тем самым указываем MVC, что нужно визуализировать представление. Экземпляр ViewResult создается вызовом метода View() без параметров. Это указывает инфраструктуре MVC на то, что для действия необходимо визуализировать стандартное представление.

Если запустить приложение на этом этапе, легко убедиться, что MVC Framework пытается найти для использования стандартное представление по умолчанию, как показано в сообщении об ошибке на рисунке ниже:

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

Не удалось найти представление «Index» или его образец, либо ни один обработчик представлений не поддерживает места поиска. Выполнялся поиск в следующих местах:

Данное сообщение об ошибке исключительно полезно. Оно не только поясняет, что инфраструктура MVC не смогла найти представление для метода действия, но и показывает, где производился поиск. Это еще одна хорошая иллюстрация соглашения MVC: представления ассоциируются с методами действий с помощью соглашения об именовании. Метод действия называется Index(), а контроллер — Home, и, как видно на рисунке, инфраструктура MVC пытается найти в папке Views файлы с таким именем.

Простейший способ создания представления предусматривает поручение этой работы среде Visual Studio. Щелкните правой кнопкой внутри определения метода действия Index() в окне редактора кода, в котором открыт файл HomeController.cs, и выберите в контекстном меню пункт Add View (Добавить представление), как показано на рисунке ниже:

Во вкладке View Создайте папку Home

В этой папке добавьте View

Назовите созданный View Index

Уберите галочку использовать шаблон

Не переживайте, если в настоящий момент все эти опции непонятны — они будут подробно объяснены позже. Щелкните на кнопке Add (Добавить), чтобы создать новый файл представления.

Среда Visual Studio создаст новый файл по имени Index.cshtml в папке Views/Home. Если это не то, что вам хотелось, удалите созданный файл и попробуйте проделать все заново. Это еще одно соглашение MVC Framework: представления помещаются в папку Views, организуясь внутри нее в папки, имена которых соответствуют именам ассоциированных с ними контроллеров.

Расширение файла .cshtml обозначает представление C#, которое будет обработано механизмом визуализации Razor. Ранние версии MVC полагались на механизм визуализации ASPX, файлы представлений которого имели расширение .aspx.

В результате установки опций в диалоговом окне Add View среда Visual Studio создает весьма базовое представление с содержимым, приведенным в примере ниже:

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        Привет мир (из представления)
    </div>
</body>
</html>

Добавьте внутрь тега <div> текст «Привет мир (из представления)»

Запустите проект.

Результат отображения проекта MVC из представления

Результат отображения проекта MVC из представления

Добавление динамического вывода

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

Один из способов передачи данных из контроллера в представление предусматривает использование объекта ViewBag, который является членом базового класса ControllerBase.

Объект ViewBag — это динамический объект, в котором можно устанавливать произвольные свойства, делая эти значения доступными в любом визуализируемом далее представлении. В примере ниже демонстрируется передача простых динамических данных в файле HomeController.cs указанным способом.

Код контроллера с динамическим выводом

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

namespace WebApplication7.Controllers
{
    public class HomeController : Controller
    {
        // GET: Default
        public ActionResult Index()
        {
            int hour = DateTime.Now.Hour;
            ViewBag.Greeting = hour < 12 ? "Доброе утро" : "Доброго дня";
            
            return View();
        }
    }
}

Код представления с динамическим выводом

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div> 
        @ViewBag.Greeting (из представления)
    </div>
</body>
</html>

 

Задание.

Динамически вывести таблицу 12 на 12 ячеек и заполнить ее рамочку единицами а центральную часть нулями.

Результат динамического вывода таблицы MVC

Результат динамического вывода таблицы MVC

ASP.NET MVC Решение задания к первому уроку.