Репутація українського ІТ. Пройти опитування Асоціації IT Ukraine
×Закрыть

ASP.NET 5: что изменилось для разработчика

Всем привет. В прошлой статье я рассказывал о том, что изменилось в инфраструктуре ASP.NET и CLR. Теперь самое время поговорить об изменениях, связанных с разработкой приложений. Пока я писал, ASP.NET успел обновится, поэтому, можно считать, что это уже вторая версия.

Эту статью я решил построить на примере создания MVC 6 приложения с пустого проекта. Если вы захотите повторить то, что я буду описывать, вы можете это сделать в любой редакции Visual Studio 2015. На всякий случай — бесплатная редакция Visual Studio Community.

Важно:
1. После установки Visual Studio нужно обновить Microsoft ASP.NET and Web Tools 2015 до beta 8 (на сейчас последняя версия).
2. Запустить «Developer Command Prompt for VS2015» и выполнить 2 команды: dnvm setup и dnvm upgrade.

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

Итак, создаем новый проект как обычно: File -> New Project -> Web.

И вот оно, первое изменение — раньше в разделе «Web» мы видели разные типы проектов ASP.NET (WebForms, MVC, WebApi), а теперь только «ASP.NET Web Application». И это не просто так: это тонкий намек на то, что не имеет значения, какой подход вы хотите использовать (WebForms, MVC, WebApi) — это теперь часть единого движка.

Но появились 2 новых типа проектов:

Class Library (Package) — это возможность создания библиотеки для вашего сайта и запаковать ее в nuget пакет. Почему именно nuget? Это часть новой стратегии управления зависимостями. Теперь все подключаемые библиотеки тянутся через package manager. При этом не важно, они лежат локально или онлайн. На самом деле и сам ASP.NET при упаковке для отправки на сервер сворачивается в nuget пакет.

Console Application (Package) — это вообще что-то из ряда вон выходящее. Консольное приложение для веб проекта. Зачем? На самом деле, этот тип проекта появился для создания собственного веб сервера на случай, если вы не хотите использовать Kestrel, WebListener или IIS. Например, вы просто хотите перенаправлять все запросы по порту 80 в ASP.NET и не проводить какие-то фильтрации, преобразования и прочее (ну или хотите написать свой уникальный веб сервер).

С этим, думаю, понятно. Дальше выбираем ASP.NET Web Application -> OK:

Как видим, все наши типы проектов спрятались в этом открывшемся окне. В данном случае нас интересует ASP.NET 5 Preview Templates. И опять вопрос: где же наши MVC, WebApi, WebForms шаблоны? Это еще один тонкий намек на то, что теперь все едино.

При этом внизу мы видим чекбоксы для выбора шаблона, но для ASP.NET 5 проектов они не активны. Это уже конкретный, толстый намек, граничащий с издевательством (можно было эти контролы просто скрыть), что теперь деваться некуда и придётся разбираться с новой структурой проектов и подходом к созданию ASP.NET приложений. Жмем «ОК», и через какое-то время у нас открывается новый пустой проект.

Будем превращать его в MVC проект шаг за шагом, попутно останавливаясь на особенностях нового шаблона.

Подключение библиотек

Первое что необходимо сделать на пути превращения пустого проекта в MVC — добавить необходимые для MVC библиотеки (References). Это можно сделать двумя способами:
1. Классический (в Solution Explorer, правой кнопкой по «References» -> Add Reference)
2. Продвинутый (ручной), используя файлик project.json.

Давайте рассмотрим структуру project.json по блокам в данном проекте:

webroot — директория на сервере, куда будет опубликовано наше приложение.
version — это версия приложения. Никакой связи с версией CRL или еще чего-то не имеет.

Тут то как раз мы и подключаем необходимые для нашего MVC библиотеки. Нужно дописать одну строку: «Microsoft.AspNet.Mvc»: «6.0.0-beta8». Рекомендую вводить руками, intellisense (он тут работает) вам подскажет версию библиотеки. У вас может стоять не «6.0.0-beta8», а какая-то другая версия.

И тут начинается магия: как только ввели новую строку и сохранили изменения, вы можете заметить, как в Solution Explorer раздел References начинает обновляться:

Как вы, наверное, догадались, Visual Studio автоматом докачивает только что добавленную библиотеку из nuget и сохраняет ее в кеш (и, соответственно, добавляет в ваш проект). Если вы сотрете только что созданную строку в project.json, Visual Studio уберет ее из References в вашем проекте, но при повторном добавлении этой строки, библиотека подключится уже из кэша, без закачки из онлайн репозитория.

Также, раз уж мы смотрим на References, обратите внимание, что здесь нет привычной простыни из подключенных библиотек. Все они спрятаны в разделы DNX 4.5.1 и DNX Core 5.0 в виде дерева (что такое DNX, читайте в предыдущей статье). Дерево — это зависимости одних библиотек от других. По-моему, очень удобное отображение.

Вопрос: откуда взялся DNX 4.5.1 и DNX Core 5.0 в нашем проекте? Опять таки, из project.json:

Если мы удалим, например, строчку с dnx451, то весь раздел DNX 4.5.1 пропадет из References в Solution Explorer. Иными словами, раздел «frameworks» указывает, под какие фреймворки будет собран наш проект. Причем в каждом из них можно создать свой набор зависимостей аналогично тому, как это делалось выше, там, где мы добавляли библиотеку MVC.

Далее блок «commands»:

Это команда запускает dnx для старта вашего приложения.

Ну и последние 2 блока:

publishExclude — компоненты, которые не нужно включать в пакет публикации.
exclude — компоненты, которые нужно игнорировать при компиляции.

Более детальная информация о структуре project.json есть тут.

Закрываем наш project.json и идем дальше.

Запуск сервиса и обработка запросов

Для того, чтобы наш проект стал MVC, нам необходимо сделать еще 2 вещи:
1. Запустить сервис MVC (тут понятие сервис несет немножко иной смысл, нежели сервис (служба) в Windows).
2. Добавить компонент MVC в процедуру роутинга трафика для веб сервера.

Все это делается в файлике Startup.cs. Как вы понимаете, это входящая точка нашего проекта.

Видим два метода. Первый — ConfigureServices. Тут начинается эпопея с новым механизмом DependencyInjection. Детально изучить этот механизм можно тут. Я же расскажу вкратце, применительно к нашей задаче.

В методе ConfigureServices мы добавляем и настраиваем все сервисы, которые будем использовать в нашем приложении. Сервисом может быть любая логика, которую нужно расшарить для всех компонентов приложения, например, Db Context, Logger.

Выглядит это примерно так: приложение говорит «Эй там, наверху, DbContext мне сюда подайте, хочу в него записать чего-нибудь». Этот крик доходит до ServiceProvider, который в ответ отдает объект DbContext. Идея в том, что попросить вернуть экземпляр требуемого нам сервиса мы можем откуда угодно в нашем проекте.

Если вы хотите попробовать DI механизм в деле, можете это сделать по инструкции тут.

Наша задача на сейчас — добавить строчку services.AddMvc(); в метод ConfigureServices. AddMvc — это Extension метод, который появляется вместе с пакетом Microsoft.AspNet.Mvc, который мы добавляли ранее.

Второй метод, Configure, служит для настройки последовательности обработки HTTP запросов.

Ввиду того, что MVC сам по себе является частью этой последовательности (ловит запрос, парсит url параметры, направляет на нужный контроллер), его нужно добавить и сюда, при этом настроить маршрут по умолчанию. В итоге Startup.cs должен выглядеть так:

Обратите внимание на строчку app.UseIISPlatformHandler();. Использование IIS HttpPlatformHandler позволяет завернуть трафик IIS на используемый нами Kestrel или WebListener. Прежде, чем использовать его на сервере, нужно сделать предварительную установку этого компонента в IIS (ссылки для x86, x64).

Что значит появление этого компонента в нашем проекте? Ранее, в версиях ASP.NET до Beta 8, работу с IIS обеспечивал Helios, который по сути являлся еще одним хостом со своей логикой. С выходом Beta 8 от него отказались в пользу дополнительного нативного модуля IIS HttpPlatformHandler. Используя этот модуль, IIS запускает внешний процесс (в нашем случае dnx.exe) и перенаправляет трафик на него.

Главное запомнить: ConfigureServices — сервисы, которые мы шарим по всему нашему приложению (MVC является таким сервисом), Configure — включение какого-либо Middleware в последовательность обработки HTTP запросов. Тут даже в названиях методов скрыт сакральный смысл: добавляем сервис — services.AddMvc(), используем Middleware — app.UseMvc().

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

Теперь осталось создать контроллеры и представления. Создаем 2 папки в нашем проекте: «Controllers» и «Views».

В папку Controllers добавляем (правой кнопкой мышки по папке -> Add -> New Item -> MVC Controller Class) контроллер «HomeController». В папке «Views» создаем папку «Home» и добавляем туда (правой кнопкой мышки по папке -> Add -> New Item -> MVC View Page) представление «Index».

В итоге структура проекта должна быть такой:

Дабы не было скучно, давайте что-то отобразим на нашей веб страничке. В контроллере для метода действия (другого перевода для Action в данном контексте не нашел) Index напишем:

А в представлении:

Теперь можем запустить приложение, и — та-да — в браузере «Hello World!». MVC без обмана. :)

Структура проекта

Еще буквально пару слов о структуре.

Папка wwwroot в проекте в Visual Studio — это вся статика нашего приложения. CSS, картинки и прочее, всё кидаем туда. Приятная новость: мы можем добавлять туда файлы с помощью Windows Explorer (т.е. не в Visual Studio), и они тут же подтянутся в ваш Solution Explorer. В Visual Studio 2015 встроен File System Watcher, который отслеживает все изменения в файлах вашего проекта и подтягивает их в ваш проект. В таком же виде содержимое этой папки развернется на сервере в папке wwwroot.

Dependencies в проекте — это не тоже самое, что Dependencies в project.json. Сюда попадают скрипты из Bower и NPN. Это 2 дополнительных package manager, которые используются для подтягивания клиентских зависимостей (например, JavaScript библиотек jquery) или скриптов для потоковой сборки проектов (GulpJS). Попробуйте создать новый проект, только шаблон выберите ASP.NET Web Application. Посмотрев в Dependencies, всё поймете.


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

В следующем материале, по просьбам комментаторов предыдущей статьи, я расскажу о способах публикации ASP.NET 5 приложений. Ну а в дальнейшем продолжу раскрывать изменения для разработчиков (типа «как заменить настройки, которые ранее делались в Web.config», «MVC 5 vs MVC 6, что изменилось?»).

P.S. Если вы хотите почитать о чем-то конкретном — пишите в комментариях, я постараюсь учесть ваши пожелания в последующих статьях.

P.P.S. Ну и конечно еще больше деталей от крутых спикеров со всего мира вы можете узнать на конференции DevDay*Kyiv, которая пройдет уже на следующей неделе.



Предыдущая часть:
— ASP.NET 5 — взгляд внутрь. Об изменениях ядра и инфраструктуры
Продолжение:
— ASP.NET 5: публикуем приложение на Linux
— ASP.NET 5: публикуем приложение на Windows Server

LinkedIn

Похожие статьи

37 комментариев

Подписаться на комментарииОтписаться от комментариев Комментарии могут оставлять только пользователи с подтвержденными аккаунтами.

коли з nuget випілять frontend ліби?

а зачем это делать? если они вам не нужны просто не качайте фронт-енд с nuget

а legacy code?
вангую що в проектах буде каша. до vs2015 проекти були завязані на nuget(якщо це frontend, то це вже каша), тепер сама ms підштовхує до bower і тд.
зручно буде підтримувати такий мікс?

Ну так legacy это как раз еще это одна причина почему их нельзя удалять, ибо старые проекты перестанут билдится из-за отсутствий пакетов. И плюс bower + nuget вполне норм связки, и такой она и должна быть. Так как без nuget-а всеравно никак. И bower облегчит только frontend часть. Ну и плюс npm\grunt.

коли з nuget випілять frontend ліби
поки є можливість додавати через nuget фронтенд, цим хтось буде користуватись. поки цим буде хтось користуватись, буде каша в структурі(те що зараз робить nuget це ж треш).
імхо, це треба як з mvc5 або edge. взяти, і повністю переробити(точніше заборонити фронтент через nuget)

У вас есть выбор, либо использовать frontend пакеты из nuget-а(что лишено смысла, так как они особо не обновляются после появления bower-а), либо использовать bower. Правильных подход оставить выбор на конкретный проект, что им удобнее. Имхо, принуждать и убирать пакеты принудительно, что вызовет тонны возмущений тех, кто их использует, и у кого поломаются билды, которые нужно мигрировать на bower, и добавлять интеграцию с ним, потом добавлять это в билд сервер и так далее, что может быть не таким быстрым таском. Поэтому, имхо, это правильно оставить их там и оставить выбор.

У вас есть выбор
це якщо я починаю проект) якщо мені дають уже готовий, з спегетті-структурою, вибору особо і нема.

Вам же ничего не мешает заменить зависимости nuget-а для frontend-а на bower :) Ну и плюс обновить процесс билда, чтобы bower использовался.

Все, что они сделали — переписали ASP.NET и сделали из него NodeJS, только на C#. Кто писал на ноде и трогал новый ASP.NET меня поймет :)

Тоже в свое время можно было сказать про MVC и RoR

Я не говорю, что это плохо :) Это хорошо, поскольку чтобы использовать те же подходы тебе теперь не нужно менять фреймворк

Можно пример, где в новом ASP.NET тот же подход, что и в nodejs?

Пока то, что я видел:
1) не работало
2) имело кучу неинтуитивных вещей
3) overengineered

До релиза .NET Core & ASP.NET 5 где-то от 3-6 мес и применять в продакшне я бы его стал только через год — не ранее.
Только вот зачем мне ждать год, если есть NodeJS? :)
З.Ы. Сильно я сомневаюсь в светлом будущем нового ASP.NET — идея классная, но запоздалая

Успеть запрыгнуть в уезжающий поезд

Ждать год чего? когда с# потеряет типизацию и станет работать в один поток?

Зачем ему работать в один поток? C# язык общего назначения, универсальный, с кучей фич и сахара, ну а javascript — язык и король фронтенда.
Хочется больше сахара и типизации? Typescript :)

Думаю, никто не будет спорить, что никто не пишет современные веб приложения без angular, react, gulp, npm etc...это нонсенс.
Нужно просто правильно выбирать инструменты для задач. Вот во фронтендах лидерство NodeJS сейчас неоспоримо благодаря асинхронной модели, отличной масштибируемости, самом большом репозитории пакетов npm и тд.
Ну а на ASP.NET и С# можно продолжать писать бэкэнды :)

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

Только вот зачем мне ждать год, если есть NodeJS? :)

Не ждите.
В остальном толстоватый вброс у вас получился.

По поводу древовидной стуктуры references: правильно ли я понял, что теперь можно подключить две версии одной библиотеки в разных ветвях дерева? Если это так, то как будет определятся версия если я использую библиотеку из своего кода?

Как с бандлингом javascript/css? Если теперь asp.net знает о существовании grunt’a и bower’a, логично их использовать. Но я не нашел ничего в beta2 версии.

Не совсем понял в чем вопрос. Если вопрос в том, как использовать grunt и bower в проектах ASP.NET 5 — можно почитать тут. Что касается beta2 — тяжело сказать, ибо я обновился с beta5, которая прилетела вместе Visual Studio 2015 до beta8, что и тебе рекомендую.

Подробней: в предыдущих версиях ASP.NET присутствовал бандлинг, можно было конфигурировать наборы js/css файлов, которые вставлялись во вьюхи. Это решало две проблемы — разделять клиентский код по модулям, что бы не грузить лишнего и минифицировать его всем скопом при запуске релизного аппликейшена. Как это делается в asp.net 5?
docs.asp.net/...ing-and-minification.html — судя по всему, тема пока что открыта.

Если раньше бандлинг осуществлялся путем конфигурации в BundleConfig, то сейчас насколько я знаю, все это дело выпилено, и разработчикам предлагается пользоваться вышеуказанными Grunt/Gulp/etc.
stephenwalther.com/...runt-uglify-and-angularjs
здесь приведен пример с Grunt’ом

Есть замеры производительности IIS-hosted vs self-hosted веб-приложений?

Я не видел, но тема интересная :) Думаю об этом тоже можно написать статью. Поднять в Azure 3 одинаковые по ресурсам виртуалки: Windows IIS, Windows Self-Host, Linux Kestrel и провести нагрузочный тест через Visual Studio Online. Сделаю, расскажу о результатах (самому интересно).
Если есть пожелания в сетапу для нагрузочного деста — в студию! :)

Еще есть предложение сравнить возможности SignalR и др. решений с Go, node.js

Жду статью про то как создать свой docker image с asp.net 5

Андрей, а с чем связан интерес именно к Docker? Теперь же можно запускать ASP.NET на Linux без него.

В нем удобней хостить и быстрее разворачивать

P.S. Если вы хотите почитать о чем-то конкретном — пишите в комментариях, я постараюсь учесть ваши пожелания в последующих статьях.

Кто следит за состоянием Http контекста, если один запрос выполняется в разных потоках. Все ли текущие реализации веб серверов для нового асп.нет поддерживают данный случай.
---
Вопрос неактуальный. Статику везде ж убрали из ASP.NET.

Еще один такой переход и буду писать на NancyFX :/

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

Сделала, прошу прощение за ошибку

Зображення в статті не на своїх місцях

Исправьте NPN на NPM :)

Полезная статья, спасибо

Подписаться на комментарии