В этой статье я расскажу, как вы можете добавить страницы на основе Blazor в существующее приложение Razor Pages.
Предисловие
Выход Blazor на золото должен произойти через две недели. Многие вещи в проекте еще подвержены достаточно резким изменениям, и последняя предварительная 9-я версия значительно усложнила взаимодействие между компонентами Razor Pages и Blazor: теперь невозможно передавать параметры из страницы Razor в компонент Blazor с помощью
Html.RenderComponentAsync
.
Это может измениться в будущем, но вполне вероятно, что в .NET Core
3.0 он появится с этим ограничением.Если вы все же хотите улучшить свое существующее приложение на основе Razor Pages с помощью Blazor-магии, одно из решений полностью создавать свои страницы в Blazor. В этой статье я покажу, как вы можете добавлять Blazor-страницы в существующее приложение на основе Razor Pages, где одни части приложения создаются с помощью Razor Pages, а другие с помощью Blazor Pages. Для обоих типов страниц используется одинаковый макет.
Шаг первый: поддержка Blazor
Итак, у нас есть уже существующее Razor Pages приложение, которое было преобразовано в .NET Core 3.
Для начала, вам нужно добавить в свое приложение поддержку Blazor. Эта поддержка позволит вам отображать Blazor-компоненты с Razor-страницы. Официальная документация полностью проводит вас по этому процессу, но вот его краткое изложение.
Startup.cs:
Нам необходимо добавить
Services.AddServerSideBlazor
в
ConfigureServices
и
endpoints.MapBlazorHub
в Configure
:_Layout.cshtml:
JS-библиотека Blazor необходима для подключения Blazor на стороне сервера. Она может быть добавлена в
_Layout.cshtml
:?
<script src="_framework/blazor.server.js"></script>
_Imports.razor:
Нам также потребуется новый файл с именем
_Imports.razor
. Он должен быть добавлен в папку
Pages:_Imports.razor
используется для установки
using-выражений для ваших Blazor-компонентов. Начать можно со
следующего:?
@using System.Net.Http@using Microsoft.AspNetCore.Components.Forms@using Microsoft.AspNetCore.Components.Routing@using Microsoft.JSInterop@using Microsoft.AspNetCore.Components.Web
И на этом все. Теперь наше приложение поддерживает Blazor. Мы можем проверить это, скопировав классический компонент Counter (счетчик) в наше приложение
?
@page "/counter" <h1>Counter</h1><p>Current count: @currentCount</p> <button class="btn btn-primary" @onclick="IncrementCount">Click me</button> @code { int currentCount = 0; void IncrementCount() { currentCount++; }}
И отредактируем
Privacy.cshtml
, чтобы включить
компонент Counter:
<a href="http://personeltest.ru/aways/mikaelkoskinen.net/post/combining-razor-blazor-pages-single-asp-net-core-3-application#">?</a>@page@model PrivacyModel@{ ViewData["Title"] = "Privacy Policy";}<h1>@ViewData["Title"]</h1> <p>Use this page to detail your site's privacy policy.</p> <component>@(await Html.RenderComponentAsync<Counter>(RenderMode.Server))</component>
Теперь, когда мы запускаем приложение, на нашей странице должен появится рабочий Counter:
В следующей части этой статьи я покажу, как вы можете изменить свое Razor Pages приложение, чтобы вместо простого добавления компонентов на существующие страницы вы могли создавать полноценные Blazor-страницы.
Шаг второй: поддержка Blazor Pages
Наш Blazor-компонент определяет маршрут
/counter
:Но переход по нему не работает:
Наша цель заставить работать маршрутизацию на Blazor-страницы. И мы хотим, чтобы Blazor-страницы использовали тот же макет, что и Razor-страницы. Для этого нам понадобится несколько вещей, начиная с маршрутизатора (Router).
App.razor:
Создайте новый файл
App.razor
в папке
Pages
:Компонент Router определен в
App.razor
:?
@using Microsoft.AspNetCore.Components.Routing <Router AppAssembly="typeof(Program).Assembly"> <Found Context="routeData"> <RouteView RouteData="routeData"/> </Found> <NotFound> <h1>Page not found</h1> <p>Sorry, but there's nothing here!</p> </NotFound></Router>
Router автоматически просматривает все Blazor-компоненты с помощью page-директивы и добавляет к ним маршруты.
_Host.cshtml:
Нам также нужна страница, которая будет использоваться как хост для Blazor-страниц. Ее можно назвать как угодно, но в шаблонах Blazor по умолчанию используется
_Host.cshtml
, которое вполне
нас устроит (впрочем, как и любое другое). В
_Host.cshtml
мы можем определить макет, который в
нашем случае будет таким же, как у Razor-страниц._Host.cshtml
содержит вызов
Html.RenderComponentAsync
:?
@page "/blazor" @{ Layout = "_Layout";} <app> @(await Html.RenderComponentAsync<App>(RenderMode.Server))</app>
Startup.cs:
И, наконец, небольшое дополнение к методу
Configure
Startup.cs
. Ранее мы добавляли MapBlazorHub
, а
теперь нам нужно добавить вызов MapFallbackToPage
,
указывающий на новый _Host.cshtml
:И на этом все! Теперь нам просто нужно протестировать наш сетап. Добавьте счетчик страниц Blazor (Counter) в свой макет, отредактировав
Pages/Shared/_Layout.cshtml
:Когда мы запускаем приложение, мы видим рабочую Blazor-страницу в нашем Razor Pages приложении:
И мы не ломали поддержку добавления Blazor-компонентов в Razor Pages:
Примечания
Следует отметить пару моментов:
- Маршруты Blazor работают только тогда, когда они указывают на
корень. Если /counter изменить, например, на
/products/counter
, страница не сможет загрузить требуемыйblazor.server.js
. Вместо этого мы получим 404. Должна быть возможность изменить тег script, чтобы он мог загружать требуемый скрипт независимо от локации, но, похоже, это изменилось с предварительной 8-й версии в предварительной 9-й, и я не смог заставить его работать. Вот скриншот 404, показывающий проблему: - Если вам удалось загрузить скрипт, вы, вероятно, столкнетесь с теми же проблемами с Blazor hub: скрипты пытаются найти hub в /products/blazor вместо blazor. Чтобы обойти это, вы можете вручную запускать соединение между сервером и браузером:
?
<script src="~/_framework/blazor.server.js" autostart="false"></script><script> Blazor.start({ configureSignalR: function (builder) { builder.withUrl('/_blazor'); } });</script>
Пример кода
Пример кода для этого проекта доступен на GitHub.
Хотите узнать о нашем курсе подробнее? Вам сюда.