ASP .NET MVC

Программирование и разработка сайтов с использованием технологии ASP .NET MVC

Обзор ASP .NET MVC

Совсем недавно хотел прочитать доклад по MVC, но военкомат решил, что я что-то должен родине. Придётся делиться знаниями с тобой %username% через этот бложик. Статья рассчитана на людей хоть чуть-чуть знакомых с ASP.Net. В сети много статей, в которых авторы говорят, что все вокруг сговорились и врут нам с тобой %username%, не дают разобраться в данном паттерне, а вот автор, из-за своего добродушия, рассказывает, что же это на самом деле. Данная статья не претендует на звание лучшей, полной или ещё какой-то, я просто описываю то, что знаю.

MVC (Model-View-Controller) – это шаблон архитектуры программного обеспечения. Суть данного паттерна в том, что данные, логика и интерфейс разделены на отдельные составляющие.

  • Model – модель данных. Часть приложения, содержащая в себе бизнеслогику, она описывает какую-то предметную область. Модель знает как устроены данные и как с ними работать, она понятия не имеет о контроллере и представлении. Основная цель паттерна сделать так, что бы модель ничего не знала об остальных частях приложения, что позволит бес проблем менять представление или контроллер этой модели.
  • View – представление. Это та часть, которая визуализирует модель данных. Обычно представление имеет прямой доступ к модели, но разрешено только чтение этих данных. Для работы с контроллером реализует в себе некий интерфейс, который известен контроллеру, а представление умет с ним работать.
  • Controller – контроллер. Компонент, немного, знающий о представлениях и что есть модель. Из названия становится понятно, что это то, что контролирует остальные части программы, он реагирует на какие-то события и, исходя из этого, влияет на модель или представление.

История MVC

Появился он чуть позже ООП, примерно в конце 70х годов. Впервые MVC описан в 1979 году Trygve M. H. Reenskaug в научно-исследовательском центре XEROX PARC для языка Smalltalk. Оригинальное описание данного шаблона находится в книге «Applications Programming in Smalltalk-80: How to use Model–View–Controller». Если часок пакопашиться в сети, то можно увидеть, что существует несколько модификаций шаблона MVC, одна из наиболее известных – Model-View-Presenter (MVP), которая появилась в 1990 году.

MVC и WEB разработка

Чем удобен данный подход для разработки WEB приложений? Для ответа на данный вопрос давайте разберемся, что такое web приложение. Это, какие-то серверные процессы, выдающие пользователю представление о них. Всё это реализуется с помощью:

  • Протокола передачи данных HTTP
  • Стандартов описания интерфейса HTML/CSS
  • Принцип работы «запрос-ответ»

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

  • ASP
  • LAMP(Linux, Apache, MySql, PHP)
  • ASP.NET
  • JSP
  • E.t.c…
  •  

При разработке WEB возникает множество проблем, основные это:

Внешний вид страниц часто изменяется, при этом

Иногда нужно несколько вариантов представления одной и той же страницы

  • Разные браузеры (IE, Firefox, Safari, Opera, ...)
  • Разные платформы (PC, телефон, КПК, ...)
  • Разные модели отображения (графические, текстовые, ...)
  • Сложно тестировать.
  •  

Если вникнуть в суть MVC , то становится понятно, что с данным подходом все эти проблемы решаются более просто, т.к. каждый занимается своим делом, не дёргая при этом другого. Меняется внешний вид - пусть дизайнеры парятся над представлениями. Нужна поддержка разных браузеров и устройств – дизайнеры работают над представлениями, а разработчики пишут код, который выдаёт устройствам нужную ему разметку. Тестировать в MVC проще простого. Можно тестировать модель и контроллеры отдельно с помощью unit тестов.

Реализаций данного подхода очень, очень много:

PureMVC, Maverick.NET, Symfony, Monorail, Joomla, Dojo, ProMesh.NETMach-II, Model-Glue, FuseBox, Aranea, Cocoon, Grails, GWT, Spring, Struts, Stripes, Tapestry, WebObjects, Wicket, JSF, SproutCore, Wawemaker,Catalyst, CGI:Application, Solstice, Gantry, CakePHP, Odin Assemble, Prado, Solar, Zand Framework,Django, Pylons, Enthought, Zope, web2py, Camping, Merb, Nitro, Ramaze, Ruby on Rails… и это далеко не всё!

Мы будем рассматривать только ASP.Net MVC Framework.

ASP.Net MVC Framework

ASP.Net MVC Framework - набор библиотек от Microsoft, которые позволяют разрабатывать web приложения, используя данный паттерн. Сейчас MVC framework имеет 1.0 версию, т.е. можно разрабатывать, не боясь кардинальных изменений, как, например, в случае с preview версиями. Приятным моментом является то, что исходный код MVC Framework открыт, т.е. любой желающий может скачать его, изменить и натворить что ему угодно :) Есть ещё интересный проект MVCContrib, проект сообщества разработчиков, расширяющий базовые возможности.

Что нужно, что бы начать разрабатывать?

Самым быстрым будет скачать Web Platform Installer, запустить его, указать, что вам нужен MVC Framework, остальное Installer сделает за вас.

Далее запускаем MS Visual Studio 2008 или Web Developer 2008 Express Edition . Открываем Files > New Project > Web > ASP.Net MVC Web Application указываем путь и название проекта и жмём Ок, приступаем к разработке.

Структура базового проекта

  • С папкой Content думаю всё понятно и ничего объяснять не нужно.
  • Controllers содержит файлы [controller name].cs с кодом контроллеров.
  • Папка Model содержит классы, работающие с данными.(ADO.Net EF, LINQ или ваши собственные классы)
  • Scripts – папка для скриптов. Очень приятным моментов является то, что jQuery включён туда по молчанию.
  • Views – папка с представлениями. Внутри неё находятся подпапки - Shared и папки для контроллеров. По правилу они должны иметь с контроллером одно имя. Shared – в ней представления общие для всего сайта и главная мастер страница.
  • В файле Global.asax инициализируется таблица маршрутизации, о которой я расскажу чуть позже.

Маршрутизация (Routing)

Маршрутизация ... какое сложное и не однозначное слово. Для начала приведу цитату из MSDN.

Маршрутизация ASP.NET позволяет использовать URL-адреса, не сопоставляемые с определенными файлами на веб-узле. Поскольку URL-адрес не сопоставляется с файлом, можно использовать в веб-приложении URL-адреса, описывающие действия пользователя, вследствие чего они более понятны пользователям. В приложении ASP.NET, не использующем маршрутизацию, входящий запрос URL-адреса обычно сопоставляется физическому файлу на диске, например ASPX-файлу. Например, запрос адреса http://server/application/Products.aspx?id=4 сопоставляется файлу Products.aspx, содержащему код и разметку для отображения результата запроса в веб-обозревателе. Веб-страница использует значение в строке запроса id=4, чтобы определить, какой тип содержания следует отображать, однако это значение вряд ли будет иметь смысл для пользователя.

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

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

Опять же, для лучшего понимания приведу примеры из MSDN.

Давайте посмотрим на содержание routing таблицы в базовом проекте.

Здесь вы видите, что при старте приложение обращается в методу RegisterRoutes, который регистрирует все необходимые, и не очень, маршруты. В первой строке этого метода в таблицу добавляется маршрут, который следует игнорировать. Во второй строке описывается маршрут Default он стандартный. Суть этого маршрута – при обращении пользователя к серверу с url вида www.site.ru\param1\param2\param3 нужно обратиться к контроллеру param1 и передать его методу param2 параметр param3. Так можно создавать «красивые» url вида – www.site.ru\producs\book\10 .

Хорошим моментом является то, что маршруты поддерживают регулярные выражения.

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

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

Модель

Модель данных – наверно самое сложное и интересное в разработке. Модель работает с данными какой-то предметной области, делает всё необходимое для корректности этих данных и т.д., плюс если использовать модель провайдеров, то получится конфетка. Как реализуется модель писать не вижу смысла, т.к. в сети полно материала как реализуются BLL и DAL. Можно использовать ADO.Net Entity Framework, Linq etc …

Контроллер

Контроллеры нужны для обработки запроса, общения с моделью и отправления данных представлению. Все они наследуются от класса Controller, который является наследником ControllerBase, который поддерживает интерфейс IController. У интерфейса IController есть метод Execute, который принимает единственный параметр RequestContext, с помощью которого вы можете выдовать всё что захотите. Из вышесказанного становится понятно, что для создания собственного контроллера разработчик должен создать класс поддерживающий интерфейс IController. Самым простым является создание класса-наследника Controller , потому что в нём много полей и методов, облегчающих разработку. При создании контроллера и его методов следует обратить внимание на их именование, т.к. они связанны с маршрутами. По умолчанию у каждого контроллера вызывается метод Index. Вот пример метода LogOn контроллера AccountController который есть в каждом базовом mvc приложении.

Здесь через HTTP серверу передаются параметры и mvc framework через QueryString получает значение параметров и передаёт их методу. Имена параметров передаваемых в запросе и названия параметров метода должны быть идентичны. Также в методы можно передовать сложные классы или структуры. Иногда бывает так, что в форме есть поля совпадающие с полями класса, но мы не хотим их сопоставлять по какаим либо причинам. Для этого мы можем указать какие поля хотим сопоставлять и передовать методу, а какие игнорировать. Include – это те поля которые мы хотим свзявать а Exclude наобарот.

Методы контроллеров имеют несколько типов того что они могут возвращать.

1. ViewResult – HTML разметка представления.
2. EmptyResult - Никакого результата.
3. RedirectResult - Представляет собой редирект на новый URL.
4. JsonResult - JavaScript Object Notation результат, который может быть использован в приложении использующий AJAX.
5. JavaScriptResult - Сценариев JavaScript.
6. ContentResult - Текст.
7. FileContentResult - Загружаемый файл (с бинарным содержания).
8. FilePathResult - Загружаемый файл (с пути).
9. FileStreamResult - Загружаемый файл (с файла потока).

Также есть ActionResult он является базовым результатом для всех методов контроллера. Наследуя его можно создать собственные результаты запроса. Например RSS.

Так же для методов(к которым может обращаться пользователь) контроллера есть определённые правила.

  • Метод должен быть public.
  • Метод не может быть статическим. Отсюда понятно что он не может быть extension методом.
  • Не может быть конструкторов и полей с get, set - ами.
  • Неможет быть обобщённым типом.
  •  Не может быть методом базового класса (Controller).
  • Метод не может иметь ref или out параметров.


Фильтры действий (Action Filter)

Очень удобным является механизм «фильтров действий». Они реализуются с помощью атрибутов, которыми помечают контроллер или его метод. Фильтры действий позволяют выполнять операций помимо операций контроллеров и расширяют их действия без модификации кода. Существует несколько стандартных фильтров.

Здесь первый фильтр указывает что выполнять данный метод только если пришёл запрос типа POST. Второй то, что доступ к данному методу имеют только пользователи Андрей и Вова. Третий указывает, что при возникновении определённой ошибки отправить пользователя к определённому представлению. Последний что следует кэшировать результат запроса на 20 минут. Фильтры действий разработчики могут создавать самостоятельно. Для этого нужно создать класс, который наследуется от класса ActionFilterAtribute. Далее переопределяем методы базового класса и спокойно помечаем нужные нам методы данным фильтром. Дополнительную информацию об Action Filter можете найти в MSDN.

В сети можно найти много примеров. Например фильтр который перед отправкой разметки сжимает её GZIP ом или фильтр который регистрирует определённые параметры запроса в базе данных, например для статистики, аудита и т.д.

Фабрика контроллеров (Controller Factory)

«Фабрика» - это подход, основная суть которого создавать экземпляр класса с опредёлённым интерфейсом (в MVC Framework это IController). Если вы вернётесь и взгляните на рисунок, показывающий что происходит на сервере при запросе, то увидите что там есть интересный пункт «Создание экземпляра контроллера». Разработчик может участвовать в создании этого экземпляра.

Что для этого нужно?

  • Создать свою фабрику контроллеров.
  • Зарегистрировать её при старте приложения.

Для создания фабрики достаточно создать класс-наследник DefaultControllerFactory. Для регистрации вашей фабрики используется класс ControllerBuilder.

Что нам это даёт? Например, фабрика исходя из настроек в web.config и типа контроллера, может создать какой-то класс необходимый контроллеру и передать его конструктору. Это очень удобный механизм, можно создать очень навороченную инфраструктуру, плюс можно передавать контроллерам фейковые параметры, например для тестирования. Так же это хорошо тем, что контроллер никуда не лезет, он в конструкторе принимает всё необходимое и использует это.

Представления

Представление это то, что выдаёт разметку пользователю. Давайте посмотрим на пример кода представления.

Как вы видите здесь обычный html со вставками блоков <% %> и <%= %>. Первая нужна для управляющих конструкций(if else, foreach, while etc…), второй для вставки значения в конечную разметку. Так же есть блоки <%@ %>, их функционал схож с такими же указателями в страницах web forms.

Представления бывают строго типизированные и нестрого типизированные. Первые передают данные представлению через поле ViewData контроллера и поле Model представления.

В MVC нет такого понятия как контрол или компонент. Весть UI там реализуется через html с небольшими вставками кода, похоже на стиль PHP. Для более удобной и простой разработки представлений есть специальные Helper классы, функциональность которых можно расширить через Extension методы. Так же в разметке, выдаваемой представлениями MVC Framework, отсутствует скрытое поле _ViewState, что не может не радовать.

В представлениях MVC Framework имеется возможность замены движка. Например как описано здесь. Таким образом можно не переучивать дизайнеров вашей организации к встроенному движку MVC Framework, пусть юзает то, что уже знает :) просто дайте известный ему engine.

MVC vs Web Forms

Сколько же холиваров в сети по этому поводу… Основной вопрос это будет ли Microsoft дальше развивать web forms. Ответ – да! Несомненно! Оба подхода имеют право на существование. Оба найдут своё место, кому-то будет приятней писать mvc приложения, кому-то web forms. Наверно говорить, что один подход имеет преимущества над другим не правильно, правильно рассказать где лучше применить mvc а где web forms.

Давайте подведем итог и узнаем, что дают оба подхода.

 Web forms

  • Хранение состояния между обращениями на сервер
  • Компонентная модель серверных элементов управления
  • События элементов управления
  • Широкая поддержка графической и декларативной разработки
  • Расширяемость «за рамками» сложна

 MVC

  • Разделение логики и представления
  • Прозрачность обработки запроса
  • Легковесные объекты
  • Простое тестирование
  • Отчуждаемые компоненты
  • Широкие возможности по расширению

И при этом оба подхода работают на ASP.Net, т.е. они оба могут работать с его внутренней инфраструктурой, которая даёт:

  • Модель провайдеров
  • Механизмы кэширования
  • Шаблоны страниц
  • Состояние сеансов пользователей
  • Обработчики страниц
  • Управление клиентским кодом
  • Управление данными
  • Контекст запроса и ответа
  • И другое...

Используя это всё можно создать проект любой сложности. При этом если ваш проект работает с огромным кол-во данных и заказчик поставил вам короткие строки то, несомненно, web forms. Если же вы не ограниченны и хотите сделать сайт с «живыми» страничками, то mvc вам в руки. В общем, вся схема выбора очень хорошо обрисована вот в этой статье. Рисунок оттуда же.

Ещё можно добавить то, что сайт на mvc будет более производительный. Причина тому это viewstate и события элементов управления. Инфраструктуре ASP.Net приходится при каждом запросе восстанавливать состояние элементов управления, производить все необходимы события, реагировать на них и т.д. Если вы хотите разработать свой стартап, который будет крутится на Windows Azure или другом облаке:), в которых вы будете платить за использованные ресурсы (вычислительные мощности, трафик, память и т.д.) ,то без сомнения – MVC!!! Дешевле выйдет.

Заключение

Вот вы и узнали моё представление о ASP.Net MVC Framework и наверно у вас сложилось своё, прошу поправлять и критиковать(конструктивно) в комментариях. По каждому пункту попытаюсь написать отдельный пост, об одних только фильтрах действия можно написать 3 таких статьи. Тестирование тоже очень интересная тема.

Напомню, что я не утверждаю, что данная статья не имеет ошибок, что она самая полная или ещё что-то. Если заметили ошибку или неточность то укажите, пожалуйста! это в комментариях.

Андрей Зиненко,

[ оригинал статьи ]

 

 

 

 


К этой записи пока нет комментариев. Будьте первым.



* Ваше имя:
Сайт или блог:
* Комментарий:
Только текст, html-теги запрещены.
* Секретный код: