Рецепт идеального приложения 2
При изучении ASP.NET MVC у меня всегда возникал вопрос:
А почему в качестве "веб-морды" нельзя использовать клиента, написанного с помощью синтаксиса Razor?
И на протяжении нескольких лет это было нельзя сделать.
Собственно, а теперь это можно сделать с помощью Blazor Server.
Создадим 3 звенное приложение: клиент- сервер - база данных (на самом деле будет 2 звенное приложение без БД).
В качестве клиента будет выступать Blazor Server, в качестве “бэка” будет выступать ASP.NET Core 3.1.
Для иллюстрации возможностей Blazor Server в качестве веб-клиента, я создам приложения для работы с заметками.
Для начало создам сервер. Для создания сервера буду использовать шаблон “Empty”.
Далее необходимо создать инфраструктуру для работы приложения как Web Api. Для этого я создам директорию /Models. Понятно из названия, что в данной папке будет лежат данные, которые необходимы для приложения.
Web Api
Models
Основным сущностью моего приложения будет класс Note. Данный класс будет представлять из себя заметку.
Сущность заметки не представляет из себя ничего сложного: id - идентификатор объекта в БД title - наименования объекта description - “тело” заметке
Repository
Далее нужно создать механизм для работы с заметками. Для этого я создам репозиторий.
Реализацию самого репозитория можно посмотреть по ссылки.
Controller
Без лишних слов, код контроллера
Здесь следует упомянуть, что при создании контроллера я использовал атрибут Route. Из этого следует, что при создании маршрута не нужно указывать шаблон для маршрута.
Startup
Startup — это настройка сервисов необходимых для работы приложения, настройка самого приложения, и настройка среды. В данном случаи Startup представляет из себя почти базовую настройку приложения.
Время проверки моей “Апишки” через Postman.
Отлично! Контроллер отдает данные.
Но в текущей реализации есть один недостаток. Если я вызову мето api/notes/note/{number}
, где number - идентификатор, которого нет, то я получу не красивую ошибку.
Такая подробная информация очень полезная при отладке и её нужно записать в лог, но она абсолютно не нужна для клиента.
Для того, что выводить клиенту нужное сообщение я буду использовать Middleware. Суть промежуточного ПО в этом случаи, что я буду вызывать метод из MVC и ловить исключении, которые возникнуть входе исполнение Action’a.
Microsoft любезно предоставила возможность создавать Middleware как угодно. Единственное ограничение: пользовательский Middleware должен принимать RequestDelegate и иметь метод с сигнатурой:
Вот само промежуточное ПО:
И добавляем наш Middleware в класс Startup.cs:
И как результат я имею красивое сообщения для клиента об ошибке.
Client
Как я писал выше в качестве клиента я буду использовать Blazor Server.
Для начала создадим проект на .NET Core 3.1 по типу Empty
.
Первое что надо сделать настроить его для работы с Blazor. Для этого я внесу изменение в класс Startup.
После этого нужно создать директорию Pages. В данной директории будет храниться хост для запуска компонентов Blazor.
Для того, чтобы все компоненты могли использовать одинаковые сборки, без директивы using в начале файла, нужно создать файл _Imports.razor.
После внесенных изменений решение выглядит следующим образом:
Я подготовил проект для старта и запуска Blazor. Далее нужно реализовать сам интерфейс.
Я хочу сделать приложение похожее на изображение ниже:
Слева у меня будет часть, где будут отображаться всё существующее заметки. Справа будет карточка выделенной заметки.
Судя по всему мне нужно реализовать 3 компонента: лист с заметками, компонент самой заметки и карточка заметки.
Компонент заметки — это то, как заметка будет представлена в списки, а карточка заметки — это отображение заметки, когда пользователь "кликает" на неё
Первым делом я создам компонент NoteComponent.razor, который будет отвечать за отображение заметки в списки. Данный компонент будет принимать в качестве параметра объект Note, будет менять стиль при взаимодействии с указателем мыши, и будет выкидывать событие о клике.
Без лишних слов, код:
Далее необходимо реализовать компонент, который отображаем список всё заметок, но для начало нужно реализовать сервис для “общение” с WebApi.
Сервис должен получать данные от WebApi по http, для этого ему нужен HttpClient. Т.к. при Dispose объекта HttpClient не всегда освобождается порт, я воспользуется новой возможностью, который появился в .Net Core, IHttpClientFactory.
У HttpClient нет методов, которые позволили мне отправлять и получать данные от сервера в формате Json. Для того, чтобы получить данные в нужном мне формате мне пришлось бы сначала сделать запрос к сервера, затем считать контент и только потом десериализовать его. А т.к. сервис, в клиенте, будет неоднократно получать и отправлять данные серверу, то придется писать данный код много раз. Чтобы этого не дать я вынес данный код в методы расширения для HttCliet.
Сам сервис, который находится в клиенте:
Как по мне выглядит очень симпатично.
В самом компоненте нет ничего сложного. Если интеренсо то реализацию можно посмотреть тут.
Вот и результат:
Все что осталось для того, что реализовать то, что я хотел изначально, так это карточку заметки.
В карточке нужно отображать свойства объекта такие как: Title, Description. Так же в карточке должна быть возможность управлять конкретной заметки, а именно обновлять или удалять её.
Всё это реализовано здесь.
Результат карточки:
Заключение:
Наконец-то появилась возможность реализовывать Web-клиента на Razor.
Из основных недостатков можно отметить, что общение между сервером (где сидит клиент) и самим представление приходит через html. Если реализовать интерфейс, в котором есть 2^10 строчек в таблице. И при каждом клике добавляется ещё столько же. В этом случаи сервер будет гонять мегабайты html.
Как всегда, ссылка на репозиторий.