Поделиться через


Структура проекта для приложений Blazor

Совет

Это фрагмент из электронной книги для разработчиков ASP NET веб-формы для Azure, Blazor доступных в документации .NET или в виде бесплатного скачиваемого PDF-файла, который можно читать в автономном режиме.

Blazor-for-ASP-NET-Web-Forms-Developers eBook cover эскиз.

Несмотря на существенные различия в структуре проекта, в ASP.NET Web Forms и Blazor применяются многие схожие концепции. Здесь мы рассмотрим структуру проекта Blazor и сравним ее с проектом ASP.NET Web Forms.

Чтобы создать свое первое приложение Blazor, следуйте инструкциям в статье о начале работы с Blazor. Вы можете следовать инструкциям по созданию Blazor приложения сервера или приложения, размещенного BlazorWebAssembly в ASP.NET Core. За исключением логики размещения для конкретной модели, большая часть кода в обоих проектах одинакова.

Файл проекта

Приложения Blazor Server — это проекты .NET. Файл проекта для приложения Blazor Server максимально прост:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
  </PropertyGroup>

</Project>

Файл проекта для BlazorWebAssembly приложения выглядит немного больше (точные номера версий могут отличаться):

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
  </ItemGroup>

</Project>

Blazor WebAssemblyЦелевые Microsoft.NET.Sdk.BlazorWebAssembly объекты Microsoft.NET.Sdk.Web проекта вместо пакета SDK, так как они выполняются в браузере в WebAssemblyсреде выполнения .NET. Вы не можете установить .NET в веб-браузер, как на сервере или на компьютере разработчика. Следовательно, проект ссылается на платформу Blazor, используя отдельные ссылки на пакеты.

Для сравнения проект ASP.NET Web Forms по умолчанию включает в себя почти 300 строк XML-кода в файле . CSPROJ, большинство которых явно задает в проекте различные файлы кода и содержимого. С момента выпуска .NET 5 Blazor сервер и BlazorWebAssembly приложения могут легко совместно использовать одну единую среду выполнения.

Отдельные ссылки на сборки, хотя они и поддерживаются, не так сильно распространены в проектах .NET. Большинство зависимостей проектов обрабатываются как ссылки на пакеты NuGet. В проектах .NET требуется ссылаться только на зависимости пакетов верхнего уровня. Транзитивные зависимости включаются автоматически. Вместо того чтобы использовать для ссылок на пакеты файл packages.config, который обычно находится в проектах ASP.NET Web Forms, ссылки на пакеты добавляются в файл проекта с помощью элемента <PackageReference>.

<ItemGroup>
  <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>

Точка входа

Точка входа приложения Blazor Server определяется в файле Program.cs, как реализовано в консольном приложении. При выполнении приложение создает и запускает экземпляр хост-сайта с использованием значений по умолчанию, характерных для веб-приложений. Хост-сайт управляет жизненным циклом приложения Blazor Server и настраивает службы на уровне узла. Примерами таких служб являются конфигурация, ведение журнала, внедрение зависимостей и HTTP-сервер. Этот код в основном является стандартным, и часто его оставляют без изменений.

using BlazorApp3.Areas.Identity;
using BlazorApp3.Data;
using Microsoft.AspNetCore.Components.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
    .AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
builder.Services.AddSingleton<WeatherForecastService>();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();

app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapControllers();
app.MapBlazorHub();
app.MapFallbackToPage("/_Host");

app.Run();

Blazor WebAssembly приложения также определяют точку входа в Program.cs. Сам код выглядит немного иначе. Этот код аналогичен тому, который настраивает хост приложений для предоставления приложению тех же служб уровня узла. Однако хост приложений WebAssembly не настраивает HTTP-сервер, так как он выполняется непосредственно в браузере.

В приложениях Blazor файл Global.asax для определения логики запуска для приложения не используется. Вместо этого применяется логика, указанная в файле Program.cs или связанном классеStartup, на который ссылается Program.cs. В любом случае этот код используется для настройки приложения и всех связанных с ним служб.

В приложенииBlazor Server показанный файл Program.cs используется в целях настройки конечной точки для подключения в реальном времени, используемого Blazor между клиентскими браузерами и сервером.

Blazor WebAssembly В приложении файл Program.cs определяет корневые компоненты для приложения и где они должны отображаться:

using BlazorApp1;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

await builder.Build().RunAsync();

статические файлы;

В отличие от проектов ASP.NET Web Forms, не все файлы проекта Blazor можно запрашивать как статические файлы. Веб-адресации подлежат только файлы в папке wwwroot. Эта папка называется "веб-корнем" приложения. Все, что находится за пределами веб-корня приложения, не подлежит веб-адресации. Такая настройка обеспечивает дополнительный уровень безопасности, который предотвращает случайный доступ к файлам проекта через Интернет.

Настройка

Конфигурация в приложениях ASP.NET Web Forms обычно реализуется с помощью одного или нескольких файлов web.config. У приложений Blazor файлы web.config обычно отсутствуют. В противном случае этот файл используется только для настройки параметров, имеющих отношение к IIS, при размещении в службах IIS. Вместо этого Blazor серверные приложения используют абстракции конфигурации ASP.NET Core. (BlazorWebAssembly в настоящее время приложения не поддерживают те же абстракции конфигурации, но это может быть функция, добавленная в будущем.) Например, приложение сервера по умолчанию Blazor сохраняет некоторые параметры в appsettings.json.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

Дополнительные сведения о конфигурации в проектах ASP.NET Core см. в разделе "Конфигурация ".

Компоненты Razor

Большинство файлов в проектах Blazor являются файлами RAZOR. Razor — это язык для создания шаблонов на основе HTML и C#, который используется для динамического создания пользовательского веб-интерфейса. Файлы RAZOR определяют компоненты, составляющие пользовательский интерфейс приложения. В большинстве случаев компоненты идентичны как для сервера, так Blazor и BlazorWebAssembly для приложений. Компоненты в Blazor аналогичны пользовательским элементам управления в ASP.NET Web Forms.

Каждый файл компонента Razor компилируется в класс .NET при сборке проекта. Созданный класс захватывает состояние компонента, логику отрисовки, методы жизненного цикла, обработчики событий и другую логику. Дополнительные сведения о создании компонентов в компонентах пользовательского интерфейса для создания повторно используемых элементов пользовательского интерфейса см. в Blazor разделе.

Файлы _Imports.razor не являются файлами компонентов Razor. Вместо этого они определяют набор директив Razor для импорта в другие файлы RAZOR в той же папке и вложенных в нее папках. Например, файл _Imports.razor представляет собой стандартный способ добавления директив using для часто используемых пространств имен:

@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.AspNetCore.Components.WebAssembly.Http
@using Microsoft.JSInterop
@using BlazorApp1
@using BlazorApp1.Shared

Страницы

Где находятся страницы в приложениях Blazor? Blazor не определяет отдельное расширение файла для адресуемых страниц, например, как файлы ASPX в приложениях ASP.NET Web Forms. Вместо этого страницы определяются путем назначения маршрутов компонентам. Маршрут обычно назначается с помощью директивы Razor @page. Например, компонент Counter, созданный в файле Pages/Counter.razor, определяет следующий маршрут:

@page "/counter"

Маршрутизация в Blazor обрабатывается на стороне клиента, а не на сервере. При переходе пользователя в браузере Blazor перехватывает навигацию, а затем отрисовывает компонент с соответствующим маршрутом.

Маршруты компонентов сейчас не выводятся расположением файлов компонента, как это имеет место для страниц ASPX или Razor Pages для ASP.NET Core. Возможно, мы добавим эту функцию в будущем. Каждый маршрут должен быть указан для компонента явно. Хранение маршрутизируемых компонентов в папке Pages не имеет особого значения и является просто соглашением.

Дополнительные сведения о маршрутизации см. в Blazorразделе "Страницы", "Маршрутизация" и "Макеты ".

Макет

В приложениях ASP.NET Web Forms общий макет страницы обрабатывается с использованием эталонных страниц (Site.Master). В приложениях Blazor макет страницы обрабатывается с использованием компонентов макета (Shared/MainLayout.razor). Компоненты макета подробно рассматриваются в разделе "Страница", "Маршрутизация" и "Макеты ".

Начальная загрузка Blazor

Для начальной загрузки Blazor приложение должно:

  • указывать, где на странице следует отрисовывать корневой компонент (App.Razor);
  • добавить соответствующий сценарий платформы Blazor.

В приложении Blazor Server страница узла корневого компонента определена в файле _Host.cshtml. Этот файл определяет страницу Razor, а не компонент. Страницы Razor используют синтаксис Razor для определения адресуемой сервером страницы, которая во многом аналогична странице ASPX.

@page "/"
@namespace BlazorApp3.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    Layout = "_Layout";
}

<component type="typeof(App)" render-mode="ServerPrerendered" />

Атрибут render-mode используется для определения места, где требуется отрисовать компонент корневого уровня. Параметр RenderMode указывает способ отрисовки компонента. В следующей таблице указаны поддерживаемые параметры RenderMode.

Вариант Описание
RenderMode.Server Интерактивная отрисовка после установки соединения с браузером
RenderMode.ServerPrerendered Сначала предварительная отрисовка, а затем интерактивная отрисовка.
RenderMode.Static Отрисовка в виде статического содержимого.

Файл _Layout.cshtml содержит HTML-код по умолчанию для приложения и его компонентов.

@using Microsoft.AspNetCore.Components.Web
@namespace BlazorApp3.Pages
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <base href="~/" />
    <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
    <link href="css/site.css" rel="stylesheet" />
    <link href="BlazorApp3.styles.css" rel="stylesheet" />
    <component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
</head>
<body>
    @RenderBody()

    <div id="blazor-error-ui">
        <environment include="Staging,Production">
            An error has occurred. This application may no longer respond until reloaded.
        </environment>
        <environment include="Development">
            An unhandled exception has occurred. See browser dev tools for details.
        </environment>
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>

    <script src="_framework/blazor.server.js"></script>
</body>
</html>

Ссылка на скрипт _framework/blazor.server.js устанавливает подключение в режиме реального времени с сервером, а затем обрабатывает все взаимодействия с пользователем и обновлениями пользовательского интерфейса.

Blazor WebAssembly В приложении на хост-странице находится простой статический HTML-файл в wwwroot/index.html. Элемент <div> с идентификатором app используется для указания того, где должен быть отрисован корневой компонент.

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>BlazorApp1</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <link href="BlazorApp1.styles.css" rel="stylesheet" />
</head>

<body>
    <div id="app">Loading...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>

Подлежащий отрисовке корневой компонент указан в файле Program.cs приложения с гибкой возможностью регистрации служб посредством внедрения зависимостей. Дополнительные сведения см. в статье Внедрение зависимостей Blazor ASP.NET Core.

var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.RootComponents.Add<HeadOutlet>("head::after");

Выходные данные при создании

При сборке проекта Blazor все файлы компонентов и кода Razor компилируются в одну сборку. В отличие от проектов ASP.NET Web Forms, Blazor не поддерживает компиляцию логики пользовательского интерфейса во время выполнения.

Запуск приложения с горячей перезагрузкой

Чтобы запустить приложение Blazor Server, в Visual Studio нажмите клавишу F5 для запуска с подключенным отладчиком либо клавиши Ctrl + F5 для запуска без отладчика.

Чтобы запустить BlazorWebAssembly приложение, выберите один из следующих подходов:

  • Запустите клиентский проект непосредственно с помощью сервера разработки.
  • Запустите серверный проект при размещении приложения в ASP.NET Core.

Blazor WebAssembly приложения можно отладить как в браузере, так и в Visual Studio. Дополнительные сведения см. в разделе "Отладка ASP.NET CoreBlazorWebAssembly".

Blazor Поддержка Горячая перезагрузка сервера и BlazorWebAssembly приложений в Visual Studio. Горячая перезагрузка — это функция, которая автоматически обновляет изменения, внесенные в приложение Blazor в реальном времени, в браузере. Вы можете выбрать, включена ли горячая перезагрузка, с помощью соответствующего значка на панели инструментов:

Visual Studio 2022: пункт меню и значок

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

Visual Studio 2022: пункт меню

Кроме того, можно получить доступ к дополнительным параметрам конфигурации. Диалоговое окно конфигурации позволяет указать, следует ли включать горячую перезагрузку при отладке (вместе с режимом "Изменить и продолжить"), при запуске без отладки или при сохранении файла.

Visual Studio 2022: Горячая перезагрузка параметры конфигурации из диалогового окна

Горячая перезагрузка значительно упрощает "внутренний цикл разработки". Без Горячая перезагрузка Blazor разработчику обычно потребуется перезапустить и повторно запустить приложение после каждого изменения, перейдя к соответствующей части приложения по мере необходимости. Если используется горячая перезагрузка, в большинстве случаев изменения в выполняющееся приложение можно вносить без необходимости перезапуска. Горячая перезагрузка даже сохраняет состояние страниц, поэтому нет необходимости повторно вводить значения в формы или иным образом возвращать приложение в нужное состояние.