# Лабораторная работа №5 - Создание веб-приложения при помощи ASP.NET Core ## Цель работы Получить навыки в создании кросс-платформенного веб-приложения в среде ASP.NET Core при помощи открытых кросс-платформенных инструментов. Освоить принцип проектирования API REST. ## Ход работы 1. Установка Visual Studio Code. 2. Установка .NET (Core) SDK. 3. Настройка Visual Studio Code для работы с C# (.NET). 4. Создание ASP-NET-приложения через VS Code. 5. Запуск и отладка C#-приложения в VS Code. 6. Изучение основных концепций ASP.NET Core. 7. Изменение pipeline 8. Подключение Swagger Gen+UI для демонстрации ## Прочтите внимательно перед выполнением работы Для сдачи лабораторной работы необходимо показать работающее приложение, которое способно принимать запросы из браузера. ## Установка Visual Studio Code Visual Studio Code (VS Code) -- кросс-платформенный инструмент для разработки и не только. Очень грубо, VS Code можно считать очень прокаченным блокнотом с кучей плагинов. Плагины при этом могут быть различные: добавление иконок в дерево папок и файлов, добавление поддержки форматирования, отладки и запуска исходного кода, средства доступа к удалённым серверам, возможность работать с контейнерами и т.д. Скачать и установить Visual Studio Code можно с официального сайта: . При установке можете отказаться от добавления VS Code в контекстное меню и т.д. Единственное, что можете оставить - это добавление в PATH, если это, конечно, будет спрашиваться при установке. Почитать подробнее про PATH можно тут: . ## Установка .NET (Core) SDK Перед выполнением этого шага необходимо убедиться: вдруг на Вашем ПК уже установлено необходимое программное обеспечение. Для этого в консоли или командной строке (для Windows сейчас рекомендуется использовать PowerShell) следует набрать следующую команду: ``` dotnet --list-sdks ``` Если вывод будет содержать строку наподобие `8.0.202 [C:\Program Files\dotnet\sdk]` и номер версии будет из актуальных, то всё хорошо. В противном случае необходимо произвести установку. Для этого необходимо установить .NET SDK с официального сайта: . > ASP.NET Core - это платформа для создания веб-приложений, использующих .NET. > C# - язык программирования, позволяющий работать с .NET. После установки SDK под свою систему и возможной перезагрузки компьютера выполните повторно команду из начала раздела. Теперь она должна выводить данные корректно. ## Настройка Visual Studio Code для работы с C# (.NET) Для того, чтобы удобно работать в VS Code с C#, необходимо установить расширение [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit). После установки расширение будет отображаться что-то наподобие следующего: ![](vsc-extension-installed.png) ## Создание ASP-NET-приложения через VS Code Создайте пустую папку где-нибудь на Вашем компьютере. Постарайтесь не использовать в пути до этой папки пробелы и отличные от английских букв и цифр символы. Откройте эту папку в Visual Studio Code. Для этого выберите пункт меню "Открыть папку" (Open Folder) со стартовой страницы или меню "Файл" (File). Далее для создания нового C#-приложения нажмите F1. Должна открыться строка команд по середине VC Code сверху. В появившейся строке введите `.net new`, а затем выберите пункт ".NET: New project..." и нажмите Enter. ![](net-new-project.png) После этого выберите тип проекта как "ASP.NET Core Empty". ![](net-project-type.png) Далее введите название проекта. Например, `IntProgLw5`. На заключительном шаге выберите каталог по умолчанию. В итоге на экране просмотра файлов в последнем блоке "Solution Explorer" должно быть видно название проекта. ![](solution-explorer.png) Всё готово к первому запуску и отладке приложения! ## Запуск и отладка C#-приложения в VS Code Пока не вдаваясь в подробности некоторого сгенерированного кода, зайдите в _Program.cs_, перенесите часть строки с `=> "Hello world");` на новую и поставьте точку останова в это место. ![](breakpoint-set.png) Для запуска приложения и включения режима отладки необходимо нажать `F5`. VS Code может спросить, какой язык и какой проект необходимо отлаживать. Выберите C# и стандартную конфигурацию вашего приложения. ![](vsc-debug-run-1.png) ![](vsc-debug-run-2.png) В итоге должен открыться веб-браузер по ссылке или похожей. > _localhost_ - это домен (адрес) локального ПК. > Никто другой Ваш сайт по такому адресу не увидит. Заметьте, что выполнение программы остановилось в точке останова: ![](breakpoint-catched.png) Если у вас всё работает похожим образом, значит всё настроено правильно. ## Изучение основных концепций ASP.NET Core Перед ознакомлением с основами ASP.NET Core, необходимо ознакомиться с основами построения веб-серверов. Как минимум надо вспомнить или узнать, что такое: протокол HTTP, запрос, ответ, тип запроса (GET, POST, PUT, ...) код ответа (200 OK, 404 NOT FOUND, 500, ...), составные части URL (схема, домен, путь, query-string, hash). После этого можно переходить к основам ASP.NET Core, которые хорошо изложены тут: . Однако основные вещи изложу здесь, чтобы не заставлять вас сейчас читать столь сложный для понимания текст. ASP.NET Core, как и другие современные платформы для построения веб-приложений, использует принцип _pipeline_ - запрос от клиента (браузера) попадает в начало "конвейера", где затем каждый обработчик (практически любая функция на _C#_) может его или изменить, или пропустить без изменений, или остановить конвейер в зависимости от самого запроса. После прохождения всех обработчиков формируется ответ, который и возвращается клиенту (браузеру). Визуально это можно изобразить так: ``` <запрос> <ответ> ↑↑ ↓↓ ------------------------ | обработчик 1 | ------------------------ ↑↑ ↓↓ ------------------------ | обработчик 2 | ------------------------ ↑↑ ↓↓ ------------------------ | обработчик 3 | ------------------------ ``` Примеры обработчиков: - проверка, что запрос клиентом составлен правильно; - проверка доступа клиента к запрашиваемому ресурсу; - если по пути из запроса найден файл на веб-сервере, то можно его вернуть; - а если файл не найден, может какая-то подпрограмма может забрать обработку на себя? - "Хмм, всё, что начинается с /api, отдавайте мне, остальное мне не надо"; - отрисовка красивых страниц об ошибках (например, 404, 403, 500 и т.д.), если прошлые обработчики сказали, что запрос был плохим; - обработчик-которые складывает с специальный файл информацию о запросах (логгер или служба/подсистема логирования). Как видите, обработчиков бывает много, но этот конвейер где-то надо настроить. В ASP.NET Core для этого существуют классы _WebApplicationBuilder_ и _WebApplication_, использование которых и можно видеть в файле _Program.cs_ нашего проекта. В нашем простейшем приложении порядок обработчиков примерно такой: 1. _(неявно)_ Если запрос составлен с ошибками, выводить код `400 BAD REQUEST`. 2. _(неявно)_ Если приложение выбросило исключение, выводить специальную страницу и код `500 INTERNAL SERVER ERROR`. 3. Если поступил GET-запрос на главную страницу (`/`), то выводится строка `Hello World!`. Как видите, пока ничего сложного. Далее необходимо сопоставить наше веб-приложение (по сути это набор обработчиков запросов) с конкретным веб-сервером. Например, тем самым, что запускает ваше веб-приложение по адресу . А это делается в строке `app.Run();`. > В рамках этого руководства не будем вдаваться в подробности того, что спрятано под этой строкой, а также под командой `WebApplication.CreateBuilder(args)` из начала файла. Что находится в файлах помимо _Program.cs_, можете изучить самостоятельно. Дам только наводку, что launchSettings необходим для запуска веб-сервера, а appsettings - для настройки веб-приложения. ## Изменение pipeline После того, как вы научились запускать простейшее веб-приложение для отладки и изучили базовые понятия конвейерной обработки в ASP.NET Core, самое время этот конвейер немного поменять. Перед вами есть пример обработчика для _GET_-запросов по пути _/_. Предлагается сделать ещё как минимум несколько обработчиков для _GET_-запросов и проверить в браузере, как они будут работать. Например: - При GET-запросе _/time_ (через браузер необходимо будет перейти по адресу ) должно выводиться текущее время строкой в формате "ДД.ММ.ГГГГ ЧЧ:ММ.СС", например, "12.04.1961 09:07:00". - При запросе _/whoami_ должна выводиться информация о текущем браузере. - При запросе _/error_ должен возвращаться такой код статуса (`StatusCode`), который придёт из параметра обработчика `[FromQuery] int status`. Если не придёт, то отдавать код статуса _200 OK_. Тогда запрос в адресной строке браузера будет выглядеть примерно как и в этом случае выводить якобы ошибку о том, что нет доступа к ресурсу. В Панели разработчика на вкладке "Сеть" должен возвращаться код из query-параметра. Для работы с запросом пользователя для получения информации о браузере или параметрах этого запроса следует изучить использование переменной `context`, которая передаётся в обработчик. Там есть свойство `.Request`, которое должно Вам помочь. ## Подключение Swagger Gen+UI для демонстрации Как проверить, что новые обработчики работают корректно? Для этого необходимо установить дополнительную зависимость в приложение и добавить обработчик для отображения нового интерфейса. Для этого в "Solution Explorer" нажмите правой кнопкой мыши на название проекта (на втором уровне вложенности!) и выберите пункт "Open In Integrated Terminal". В появившейся командой строке введите команду `dotnet add package Swashbuckle.AspNetCore`. ![](swagger-installed.png) Далее в _Program.cs_ до построения приложения `builder.Build()` добавьте следующие строки: ```csharp builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); ``` > Этот код добавляет вспомогательные службы для обработчика-генератора контракта нашего API. Также до `app.Run()` добавьте следующие строки: ```csharp app.UseSwagger(); app.UseSwaggerUI(); ``` > Этот код добавляет обработчики для возврата контакта API и интерфейс для просмотра этого контракта. Чтобы проверить наши обработчики, необходимо при отладке приложения в адресной строке добавить `/swagger` к адресу сайта. Должна открыться похожая страница: ![](swagger-test.png) Пример демонстрации работы query-параметра _status_ в запросе кода ошибки: ![](swagger-error.png)