Partilhar via


Estrutura do projeto para Blazor aplicativos

Gorjeta

Este conteúdo é um excerto do eBook, Blazor para ASP NET Web Forms Developers for Azure, disponível no .NET Docs ou como um PDF transferível gratuito que pode ser lido offline.

Blazor-for-ASP-NET-Web-Forms-Developers miniatura da capa do eBook.

Apesar de suas diferenças significativas na estrutura do projeto, ASP.NET Web Forms e Blazor compartilham muitos conceitos semelhantes. Aqui, vamos examinar a estrutura de um Blazor projeto e compará-lo com um projeto ASP.NET Web Forms.

Para criar seu primeiro Blazor aplicativo, siga as instruções nas etapas de Blazor introdução. Você pode seguir as instruções para criar um Blazor aplicativo Server ou um BlazorWebAssembly aplicativo hospedado no ASP.NET Core. Exceto para a lógica específica do modelo de hospedagem, a maioria do código em ambos os projetos é a mesma.

Ficheiro de projeto

Blazor Os aplicativos de servidor são projetos .NET. O arquivo de projeto para o Blazor aplicativo Server é tão simples quanto possível:

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

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

</Project>

O arquivo de projeto de um BlazorWebAssembly aplicativo parece um pouco mais envolvido (os números exatos da versão podem variar):

<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>

BlazorWebAssemblyMicrosoft.NET.Sdk.BlazorWebAssembly destinos de projeto em vez de Microsoft.NET.Sdk.Web sdk porque eles são executados no navegador em um WebAssemblytempo de execução .NET baseado em . Você não pode instalar o .NET em um navegador da Web como em um servidor ou máquina de desenvolvedor. Consequentemente, o projeto faz referência à Blazor estrutura usando referências de pacotes individuais.

Em comparação, um projeto de Web Forms ASP.NET padrão inclui quase 300 linhas de XML em seu arquivo .csproj , a maioria das quais está listando explicitamente os vários arquivos de código e conteúdo no projeto. Desde o lançamento do .NET 5, tanto o servidor quanto Blazor BlazorWebAssembly os aplicativos podem compartilhar facilmente um tempo de execução unificado.

Embora sejam suportadas, as referências de assembly individuais são menos comuns em projetos .NET. A maioria das dependências do projeto são tratadas como referências de pacote NuGet. Você só precisa fazer referência a dependências de pacotes de nível superior em projetos .NET. As dependências transitivas são incluídas automaticamente. Em vez de usar o arquivo packages.config comumente encontrado em projetos ASP.NET Web Forms para fazer referência a pacotes, as referências de pacote são adicionadas ao arquivo de projeto usando o <PackageReference> elemento .

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

Ponto de entrada

O Blazor ponto de entrada do aplicativo Servidor é definido no arquivo Program.cs , como você veria em um aplicativo de Console. Quando o aplicativo é executado, ele cria e executa uma instância de host da Web usando padrões específicos para aplicativos da Web. O host gerencia o ciclo de vida do Blazor aplicativo Servidor e configura serviços no nível do host. Exemplos de tais serviços são configuração, registro, injeção de dependência e o servidor HTTP. Este código é principalmente clichê e muitas vezes é deixado inalterado.

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();

BlazorWebAssembly Os aplicativos também definem um ponto de entrada no Program.cs. O código parece ligeiramente diferente. O código é semelhante na medida em que está configurando o host do aplicativo para fornecer os mesmos serviços de nível de host para o aplicativo. No WebAssembly entanto, o host do aplicativo não configura um servidor HTTP porque ele é executado diretamente no navegador.

Blazor os aplicativos não usam um arquivo Global.asax para definir a lógica de inicialização do aplicativo. Em vez disso, essa lógica está contida em Program.cs ou em uma classe relacionada Startup que é referenciada a partir de Program.cs. De qualquer forma, esse código é usado para configurar o aplicativo e quaisquer serviços específicos do aplicativo.

Em um Blazor aplicativo de servidor, o arquivo de Program.cs mostrado é usado para configurar o ponto de extremidade para a conexão em tempo real usada entre Blazor os navegadores do cliente e o servidor.

Em um BlazorWebAssembly aplicativo, o arquivo Program.cs define os componentes raiz do aplicativo e onde eles devem ser renderizados:

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();

Ficheiros estáticos

Ao contrário ASP.NET projetos Web Forms, nem todos os arquivos em um Blazor projeto podem ser solicitados como arquivos estáticos. Somente os arquivos na pasta wwwroot são endereçáveis pela web. Esta pasta é referida como a "raiz da web" do aplicativo. Qualquer coisa fora da raiz da Web do aplicativo não é endereçável pela Web. Esta configuração fornece um nível adicional de segurança que impede a exposição acidental de arquivos de projeto pela Web.

Configuração

A configuração em aplicativos ASP.NET Web Forms normalmente é tratada usando um ou mais arquivos web.config . Blazor Normalmente, os aplicativos não têm arquivos Web.config . Se isso acontecer, o arquivo só será usado para definir configurações específicas do IIS quando hospedado no IIS. Em vez disso, Blazor os aplicativos de servidor usam as abstrações de configuração ASP.NET Core. BlazorWebAssembly(Atualmente, os aplicativos não suportam as mesmas abstrações de configuração, mas esse pode ser um recurso adicionado no futuro.) Por exemplo, o aplicativo Servidor padrão Blazor armazena algumas configurações no appsettings.json.

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

Você aprenderá mais sobre a configuração em ASP.NET projetos principais na seção Configuração .

Componentes da navalha

A maioria dos arquivos em Blazor projetos são arquivos .razor . Razor é uma linguagem de modelagem baseada em HTML e C# que é usada para gerar dinamicamente a interface do usuário da web. Os arquivos .razor definem componentes que compõem a interface do usuário do aplicativo. Na maioria das vezes, os componentes são idênticos para o Blazor servidor e BlazorWebAssembly os aplicativos. Os componentes em Blazor são análogos aos controles de usuário em ASP.NET Web Forms.

Cada arquivo de componente do Razor é compilado em uma classe .NET quando o projeto é criado. A classe gerada captura o estado do componente, a lógica de renderização, os métodos do ciclo de vida, os manipuladores de eventos e outras lógicas. Você aprenderá mais sobre a criação de componentes na seção Criando componentes reutilizáveis da interface do usuário com Blazor .

Os arquivos _Imports.razor não são arquivos de componente do Razor. Em vez disso, eles definem um conjunto de diretivas Razor para importar para outros arquivos .razor dentro da mesma pasta e em suas subpastas. Por exemplo, um arquivo _Imports.razor é uma maneira convencional de adicionar using diretivas para namespaces comumente usados:

@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

Páginas

Onde estão as páginas nas Blazor aplicações? Blazor não define uma extensão de arquivo separada para páginas endereçáveis, como os arquivos .aspx em aplicativos ASP.NET Web Forms. Em vez disso, as páginas são definidas atribuindo rotas aos componentes. Uma rota é normalmente atribuída usando a @page diretiva Razor. Por exemplo, o Counter componente criado no arquivo Pages/Counter.razor define a seguinte rota:

@page "/counter"

O roteamento é tratado no Blazor lado do cliente, não no servidor. À medida que o usuário navega no navegador, interceta a navegação e, em seguida, Blazor renderiza o componente com a rota correspondente.

Atualmente, as rotas do componente não são inferidas pelo local do arquivo do componente, como acontece com .aspx páginas ou ASP.NET Core Razor Pages. Este recurso pode ser adicionado no futuro. Cada rota deve ser especificada explicitamente no componente. Armazenar componentes roteáveis em uma pasta Pages não tem significado especial e é puramente uma convenção.

Você aprenderá mais sobre roteamento na Blazor seção Páginas, roteamento e layouts.

Esquema

Em aplicativos ASP.NET Web Forms, um layout de página comum é manipulado usando páginas mestras (Site.Master). Em Blazor aplicativos, o layout da página é manipulado usando componentes de layout (Shared/MainLayout.razor). Os componentes de layout são discutidos com mais detalhes na seção Página, roteamento e layouts .

Bootstrap Blazor

Para inicializar Blazor, o aplicativo deve:

  • Especifique onde na página o componente raiz (App.Razor) deve ser renderizado.
  • Adicione o script de estrutura correspondente Blazor .

Blazor No aplicativo Server, a página de host do componente raiz é definida no arquivo _Host.cshtml. Este arquivo define uma página de barbear, não um componente. O Razor Pages usa a sintaxe do Razor para definir uma página endereçável ao servidor, muito parecida com uma página .aspx .

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

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

O render-mode atributo é usado para definir onde um componente de nível raiz deve ser renderizado. A RenderMode opção indica a maneira pela qual o componente deve ser renderizado. A tabela a seguir descreve as opções suportadas RenderMode .

Opção Description
RenderMode.Server Renderizado interativamente assim que uma conexão com o navegador é estabelecida
RenderMode.ServerPrerendered Primeiro pré-renderizado e, em seguida, renderizado interativamente
RenderMode.Static Renderizado como conteúdo estático

O arquivo _Layout.cshtml inclui o HTML padrão para o aplicativo e seus componentes.

@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>

A referência de script para _framework/blazor.server.js estabelece a conexão em tempo real com o servidor e, em seguida, lida com todas as interações do usuário e atualizações da interface do usuário.

No aplicativo, a BlazorWebAssembly página host é um arquivo HTML estático simples sob wwwroot/index.html. O <div> elemento com id nomeado app é usado para indicar onde o componente raiz deve ser renderizado.

<!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>

O componente raiz a ser renderizado é especificado no arquivo de Program.cs do aplicativo com a flexibilidade de registrar serviços por meio de injeção de dependência. Para obter mais informações, consulte ASP.NET injeção de dependência principalBlazor.

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

Saída de compilação

Quando um Blazor projeto é construído, todos os componentes do Razor e arquivos de código são compilados em um único assembly. Ao contrário de ASP.NET projetos Web Forms, Blazor não suporta compilação em tempo de execução da lógica da interface do usuário.

Execute o aplicativo com o Hot Reload

Para executar o Blazor aplicativo Server, pressione F5 no Visual Studio para executar com o depurador anexado ou Ctrl + F5 para executar sem o depurador anexado.

Para executar o BlazorWebAssembly aplicativo, escolha uma das seguintes abordagens:

  • Execute o projeto cliente diretamente usando o servidor de desenvolvimento.
  • Execute o projeto de servidor ao hospedar o aplicativo com o ASP.NET Core.

BlazorWebAssembly os aplicativos podem ser depurados no navegador e no Visual Studio. Consulte Depurar ASP.NET Core BlazorWebAssembly para obter detalhes.

O Blazor servidor e BlazorWebAssembly os aplicativos oferecem suporte ao Hot Reload no Visual Studio. O Hot Reload é um recurso que atualiza automaticamente as alterações feitas em um Blazor aplicativo ao vivo, no navegador. Você pode alternar se o Hot Reload está ativado a partir de seu ícone na barra de ferramentas:

Visual Studio 2022: Hot Reload item de menu e ícone.

Selecionar o cursor ao lado do ícone revela opções adicionais. Você pode ativar ou desativar o Hot Reload, reiniciar o aplicativo e alternar se o Hot Reload deve ocorrer sempre que um arquivo for salvo.

Visual Studio 2022: Hot Reload item de menu com opções expandidas.

Você também pode acessar opções de configuração adicionais. A caixa de diálogo de configuração permite especificar se o Hot Reload deve ser habilitado ao depurar (junto com Editar e Continuar), ao iniciar sem depuração ou quando um arquivo é salvo.

Visual Studio 2022: opções de configuração Hot Reload na caixa de diálogo

O "loop interno do desenvolvedor" foi muito simplificado com o Hot Reload. Sem o Hot Reload, um Blazor desenvolvedor normalmente precisaria reiniciar e executar novamente o aplicativo após cada alteração, navegando até a parte apropriada do aplicativo, conforme necessário. Com o Hot Reload, alterações podem ser feitas no aplicativo em execução sem a necessidade de reiniciar na maioria dos casos. O Hot Reload até mantém o estado das páginas, portanto, não há necessidade de reinserir valores de formulário ou colocar o aplicativo de volta onde você precisa.