Sei sulla pagina 1di 76

Contents

Livro eletrônico Blazor para desenvolvedores do ASP.NET Web Forms


Introdução
Comparação de arquiteturas
Modelos de hospedagem
Estrutura do projeto
Inicialização
Componentes
Páginas, roteamento e layouts
Gerenciamento de estado
Formulários e validação
Como lidar com os dados
Middleware
Configuração
Segurança
Migração
Blazorpara desenvolvedores de Web Forms ASP.NET
24/07/2020 • 9 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.
DOWNLOAD disponível em: https://aka.ms/blazor-ebook

PUBLICADO POR
Divisão de Desenvolvedores Microsoft, equipes dos produtos .NET e Visual Studio
Uma divisão da Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399
Copyright © 2019, Microsoft Corporation
Todos os direitos reservados. Nenhuma parte do conteúdo deste guia pode ser reproduzida ou transmitida de
nenhuma forma nem por nenhum meio sem a permissão por escrito do publicador.
Este livro é fornecido “no estado em que se encontra” e expressa os pontos de vista e as opiniões do autor. Os
pontos de vista, as opiniões e as informações expressos neste guia, incluindo URLs e outras referências a sites da
Internet, podem ser alteradas sem aviso prévio.
Alguns exemplos aqui representados são fornecidos somente para fins de ilustração e são fictícios. Nenhuma
associação ou conexão real é intencional ou deve ser inferida.
A Microsoft e as marcas listadas em https://www.microsoft.com na página da Web "Marcas" são marcas comerciais
do grupo de empresas Microsoft.
Mac e macOS são marcas comerciais da Apple Inc.
Todas as outras marcas e logotipos são propriedade de seus respectivos proprietários.
Autores:

Daniel Roth , gerente principal de programa da Microsoft Corp.

Jeff Fritz , gerente de programas sênior, Microsoft Corp.

Taylor Southwick , engenheiro de software sênior, Microsoft Corp.

Scott Addie , desenvolvedor de conteúdo sênior, Microsoft Corp.

Introdução
O .NET tem suporte de desenvolvimento de aplicativos Web por meio do ASP.NET, um conjunto abrangente de
estruturas e ferramentas para a criação de qualquer tipo de aplicativo Web. O ASP.NET tem sua própria linhagem
de estruturas e tecnologias da Web, começando desde o início até as páginas clássicas de Active Server (ASP).
Estruturas como ASP.NET Web Forms, ASP.NET MVC, Páginas da Web do ASP.NET e mais recentes ASP.NET Core,
fornecem uma maneira produtiva e poderosa de criar aplicativos Web renderizados pelo servidor , em que o
conteúdo da interface do usuário é gerado dinamicamente no servidor em resposta a solicitações HTTP. Cada
estrutura de ASP.NET atende a uma filosofia de criação de aplicativo e público diferente. O ASP.NET Web Forms
fornecido com a versão original do .NET Framework e o desenvolvimento da Web habilitado usando muitos dos
padrões familiares aos desenvolvedores de desktop, como controles de interface do usuário reutilizáveis com
manipulação de eventos simples. No entanto, nenhuma das ofertas de ASP.NET fornece uma maneira de executar o
código executado no navegador do usuário. Para fazer isso, é necessário escrever JavaScript e usar qualquer uma
das muitas estruturas e ferramentas JavaScript que tenham sido divididas e em fase de popularidade ao longo dos
anos: jQuery, Knockout, angular, reagir e assim por diante.
Blazoré uma nova estrutura da Web que altera o que é possível ao criar aplicativos Web com o .NET. Blazoré uma
estrutura de interface do usuário da Web do lado do cliente baseada em C# em vez de JavaScript. Com Blazor você
pode escrever a lógica do lado do cliente e os componentes da interface do usuário em C#, compilá-los em
assemblies normais do .net e executá-los diretamente no navegador usando um novo padrão da Web aberto
chamado WebAssembly . Ou, como alternativa, Blazor o pode executar os componentes da interface do usuário do
.net no servidor e lidar com todas as interações da interface do usuário em uma conexão em tempo real com o
navegador. Quando emparelhado com o .NET em execução no servidor, o Blazor permite o desenvolvimento para a
Web de pilha completa com o .net. Embora Blazor Compartilhe muitas semelhanças com ASP.NET Web Forms,
como ter um modelo de componente reutilizável e uma maneira simples de lidar com eventos de usuário, ele
também se baseia nas bases do .NET Core para fornecer uma experiência de desenvolvimento Web moderna e de
alto desempenho.
Este livro apresenta ASP.NET Web Forms desenvolvedores de Blazor forma que sejam familiares e convenientes. Ele
apresenta Blazor conceitos em paralelo com conceitos análogos no ASP.NET Web Forms ao mesmo tempo em que
explica novos conceitos que podem ser menos conhecidos. Ele aborda uma ampla variedade de tópicos e
preocupações, incluindo criação de componentes, roteamento, layout, configuração e segurança. E, embora o
conteúdo deste livro seja principalmente para habilitar o novo desenvolvimento, ele também aborda diretrizes e
estratégias para migrar Web Forms ASP.NET existentes para Blazor quando você quiser modernizar um aplicativo
existente.

Quem deve usar o livro


Este livro destina-se a ASP.NET Web Forms desenvolvedores que procuram uma introdução ao Blazor que se
relaciona com seu conhecimento e suas habilidades existentes. Este livro pode ajudar na introdução rápida de um
Blazor projeto baseado em novo ou no gráfico de um roteiro para modernizar um aplicativo ASP.NET Web Forms
existente.

Como usar o livro


A primeira parte deste livro aborda o que Blazor é o e o compara com o desenvolvimento de aplicativos Web com
o ASP.NET Web Forms. Em seguida, o livro aborda uma variedade de Blazor Tópicos, capítulo por capítulo e
relaciona cada Blazor conceito ao conceito correspondente no ASP.NET Web Forms ou explica completamente
todos os conceitos totalmente novos. O livro também se refere regularmente a um aplicativo de exemplo completo
implementado em ASP.NET Web Forms e Blazor para demonstrar Blazor recursos e fornecer um estudo de caso
para migrar do ASP.NET Web Forms para o Blazor . Você pode encontrar ambas as implementações do aplicativo
de exemplo (ASP.NET Web Forms e Blazor versões) no GitHub.

O que este livro não abrange


Este livro é uma introdução ao Blazor , não um guia de migração abrangente. Embora inclua orientações sobre
como abordar a migração de um projeto do ASP.NET Web Forms para o Blazor , ele não tenta cobrir todas as
nuances e os detalhes. Para obter diretrizes mais gerais sobre como migrar do ASP.NET para o ASP.NET Core,
consulte as diretrizes de migração na documentação do ASP.NET Core.
Recursos adicionais
Você pode encontrar o Blazor Home page oficial e a documentação em https://blazor.net .

Envie seus comentários


Este livro e exemplos relacionados estão em constante evolução, para que seus comentários sejam bem-vindos! Se
você tiver comentários sobre como esse livro pode ser melhorado, use a seção de comentários na parte inferior de
qualquer página criada com base nos problemas do GitHub.

AVA N Ç A R
Uma introdução ao Blazor para ASP.NET Web Forms
desenvolvedores
24/07/2020 • 18 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

O ASP.NET Web Forms Framework foi um grampo do desenvolvimento para a Web .NET desde que o .NET
Framework foi enviado pela primeira vez em 2002. Voltando quando a Web ainda estava em grande parte,
ASP.NET Web Forms tornar a criação de aplicativos Web simples e produtiva, adotando muitos dos padrões que
foram usados para o desenvolvimento de desktops. No ASP.NET Web Forms, as páginas da Web podem ser
rapidamente compostas a partir de controles de interface do usuário reutilizáveis. As interações do usuário são
tratadas naturalmente como eventos. Há um rico ecossistema de Web Forms controles de interface do usuário
fornecidos pela Microsoft e pelos fornecedores de controle. Os controles facilitam os esforços de se conectar a
fontes de dados e exibir visualizações de dados ricas. Para o visualmente inclinado, o designer de Web Forms
fornece uma interface simples do tipo "arrastar e soltar" para gerenciar controles.
Ao longo dos anos, a Microsoft introduziu novas estruturas da Web baseadas em ASP.NET para abordar as
tendências de desenvolvimento para a Web. Algumas dessas estruturas da Web incluem ASP.NET MVC, Páginas da
Web do ASP.NET e mais recentes ASP.NET Core. Com cada nova estrutura, algumas têm previsto a recusa iminente
de ASP.NET Web Forms e críticas-la como uma estrutura da Web desatualizada e de modo desatualizado. Apesar
dessas previsões, muitos desenvolvedores da Web .NET continuam a encontrar ASP.NET Web Forms uma maneira
simples, estável e produtiva de realizar seu trabalho.
No momento da escrita, quase meio milhão de desenvolvedores da Web usam ASP.NET Web Forms todos os
meses. O ASP.NET Web Forms Framework é estável até o ponto em que documentos, amostras, livros e postagens
de blog de uma década atrás permanecem úteis e relevantes. Para muitos desenvolvedores da Web .NET,
"ASP.NET" ainda é sinônimo de "ASP.NET Web Forms" como era quando o .NET foi concebido pela primeira vez. Os
argumentos nos prós e contras do ASP.NET Web Forms em comparação com as outras novas estruturas .NET da
Web podem ser levadas em diante. ASP.NET Web Forms continua sendo uma estrutura popular para a criação de
aplicativos Web.
Mesmo assim, as inovações no desenvolvimento de software não estão lentas. Todos os desenvolvedores de
software precisam se manter atualizados de novas tecnologias e tendências. Duas tendências em particular valem
a pena considerar:
1. A mudança para software livre e para várias plataformas
2. A mudança da lógica do aplicativo para o cliente

Um .NET de software livre e de plataforma cruzada


Quando o .NET e o ASP.NET Web Forms lançados pela primeira vez, o ecossistema da plataforma parecia muito
diferente do que hoje. Os mercados de desktops e servidores foram dominados pelo Windows. Plataformas
alternativas como macOS e Linux ainda estavam lutando para obter força. O ASP.NET Web Forms é fornecido com
o .NET Framework como um componente somente do Windows, o que significa que ASP.NET Web Forms
aplicativos só podem ser executados em computadores Windows Server. Muitos ambientes modernos agora usam
diferentes tipos de plataformas para servidores e máquinas de desenvolvimento, de modo que o suporte entre
plataformas para muitos usuários seja um requisito absoluto.
A maioria das estruturas da Web modernas agora também são de código-fonte aberto, o que tem vários
benefícios. Os usuários não se comparam a um único proprietário de projeto para corrigir bugs e adicionar
recursos. Os projetos de código-fonte aberto fornecem transparência aprimorada sobre o progresso do
desenvolvimento e alterações futuras. Projetos de software livre aproveitam as contribuições de uma comunidade
inteira e estimulam um ecossistema de código-fonte aberto de apoio. Apesar dos riscos de software livre, muitos
consumidores e colaboradores encontraram atenuações adequadas que permitem aproveitar os benefícios de um
ecossistema de software livre de maneira segura e razoável. Exemplos dessas atenuações incluem contratos de
licença de colaborador, licenças amigáveis, exames de pedigree e bases de suporte.
A Comunidade do .NET adotou o suporte de plataforma cruzada e o código-fonte aberto. O .NET Core é uma
implementação de software livre e de plataforma cruzada do .NET que é executada em uma infinidade de
plataformas, incluindo Windows, macOS e várias distribuições do Linux. O Xamarin fornece mono, uma versão de
código aberto do .NET. O mono é executado no Android, no iOS e em uma variedade de outros fatores forma,
incluindo inspeções e TVs inteligentes. A Microsoft anunciou que o .NET 5 reconciliará o .NET Core e o mono em
"um único tempo de execução e estrutura do .NET que pode ser usado em qualquer lugar e que tenha
comportamentos de tempo de execução uniformes e experiências de desenvolvedor."
O ASP.NET Web Forms se beneficiar da mudança para o suporte de software livre e entre plataformas? A resposta,
infelizmente, é não, ou pelo menos não na mesma extensão do restante da plataforma. Recentemente, a equipe do
.NET tornou claro que ASP.NET Web Forms não serão portados para .NET Core ou .NET 5. Qual o motivo?
Houve esforços nos primórdios do .NET Core para a porta ASP.NET Web Forms. O número de alterações
significativas necessárias foi considerado muito drástico. Há também uma admissão aqui que, mesmo para a
Microsoft, há um limite para o número de estruturas da Web que ele pode dar suporte simultaneamente. Talvez
alguém na Comunidade demore a causa da criação de uma versão de software livre e de várias plataformas do
ASP.NET Web Forms. O código-fonte para ASP.NET Web Forms foi disponibilizado publicamente no formulário de
referência. Mas, por enquanto, parece que ASP.NET Web Forms permanecerão somente Windows e sem um
modelo de contribuição de código aberto. Se o suporte entre plataformas ou o código-fonte aberto se tornar
importante para seus cenários, você precisará procurar algo novo.
Isso significa que o ASP.NET Web Forms está inoperante e não deve mais ser usado? Claro que não! Desde que o
.NET Framework seja fornecido como parte do Windows, o ASP.NET Web Forms será uma estrutura com suporte.
Para muitos desenvolvedores de Web Forms, a falta de suporte de plataforma cruzada e de software livre é um
problema não. Se você não tiver um requisito para suporte de plataforma cruzada, software livre ou qualquer um
dos outros novos recursos no .NET Core ou no .NET 5, então, acompanhando o ASP.NET Web Forms no Windows
está bem. O ASP.NET Web Forms continuará a ser uma maneira produtiva de escrever aplicativos Web por muitos
anos.
Mas há outra tendência que vale a pena considerar, e essa é a mudança para o cliente.

Desenvolvimento para a Web do lado do cliente


Todos os. Estruturas da Web baseadas em rede, incluindo ASP.NET Web Forms, historicamente tinham uma coisa
em comum: são renderizadas pelo servidor. Em aplicativos Web renderizados pelo servidor, o navegador faz uma
solicitação ao servidor, que executa algum código (código .NET em aplicativos ASP.NET) para produzir uma
resposta. Essa resposta é enviada de volta ao navegador para manipular. Nesse modelo, o navegador é usado
como um mecanismo de processamento fino. O trabalho pesado de produzir a interface do usuário, executar a
lógica de negócios e o estado de gerenciamento ocorre no servidor.
No entanto, os navegadores se tornaram plataformas versáteis. Eles implementam um número cada vez maior de
padrões abertos da Web que concedem acesso aos recursos da máquina do usuário. Por que não aproveitar a
capacidade de computação, o armazenamento, a memória e outros recursos do dispositivo cliente? As interações
de interface do usuário em particular podem se beneficiar de uma sensação mais rica e interativa quando lidas
pelo menos parcialmente ou completamente no lado do cliente. A lógica e os dados que devem ser manipulados
no servidor ainda podem ser tratados no lado do servidor. Chamadas de API Web ou até mesmo em protocolos
em tempo real, como WebSockets, podem ser usadas. Esses benefícios estarão disponíveis para desenvolvedores
da Web gratuitamente se estiverem dispostos a escrever JavaScript. As estruturas de interface do usuário do lado
do cliente, como angular, reagir e Vue, simplificam o desenvolvimento para a Web no lado do cliente e crescem em
popularidade. ASP.NET Web Forms os desenvolvedores também podem aproveitar o aproveitamento do cliente e
até mesmo ter um suporte pronto para uso com estruturas JavaScript integradas, como o ASP.NET AJAX.
Mas a ponte de duas plataformas e ecossistemas diferentes (.NET e JavaScript) vem com um custo. A experiência é
necessária em dois mundos paralelos com linguagens, estruturas e ferramentas diferentes. O código e a lógica não
podem ser facilmente compartilhados entre o cliente e o servidor, resultando em uma sobrecarga de duplicação e
de engenharia. Também pode ser difícil acompanhar o ecossistema do JavaScript, que tem um histórico de
evolução na velocidade de batalhas. A estrutura de front-end e as preferências de ferramenta de compilação
mudam rapidamente. O setor observou a progressão de Grunt para Gulp para webpack e assim por diante. A
mesma rotatividade de Restless ocorreu com estruturas de front-end como jQuery, Knockout, angular, reagir e Vue.
Mas, considerando a monopolização do navegador do JavaScript, houve pouca escolha na questão. Ou seja, até
que a Comunidade da Web tenha se reunido e tenha causado a ocorrência de um Miracle !

WebAssemblyatende a uma necessidade


Em 2015, os principais fornecedores de navegadores ingressaram em um grupo de comunidades W3C para criar
um novo Web Standard aberto chamado WebAssembly . WebAssemblyé um código de byte para a Web. Se você
puder compilar seu código para WebAssembly , ele poderá ser executado em qualquer navegador em qualquer
plataforma em uma velocidade quase nativa. Os esforços iniciais se concentram no C/C++. O resultado foi uma
demonstração drástica da execução direta de mecanismos gráficos 3D nativos no navegador, sem plug-ins.
WebAssemblydesde que tenha sido padronizado e implementado por todos os principais navegadores.
O trabalho na execução do .NET no WebAssembly foi anunciado no final de 2017 e deve ser fornecido em 2020,
incluindo suporte do .NET 5. A capacidade de executar o código .NET diretamente no navegador permite o
desenvolvimento para a Web de pilha completa com o .NET.

Blazor: desenvolvimento para a Web de pilha completa com .NET


Por si só, a capacidade de executar código .NET em um navegador não fornece uma experiência de ponta a ponta
para criar aplicativos Web do lado do cliente. É aí que Blazor entra em. Blazoré uma estrutura de interface do
usuário da Web do lado do cliente baseada em C# em vez de JavaScript. Blazorpode ser executado diretamente no
navegador via WebAssembly . Nenhum plug-in de navegador é necessário. Como alternativa, Blazor os aplicativos
podem executar o lado do servidor no .NET Core e lidar com todas as interações do usuário em uma conexão em
tempo real com o navegador.
Blazortem excelente suporte a ferramentas no Visual Studio e Visual Studio Code. A estrutura também inclui um
modelo de componente completo da interface do usuário e tem instalações internas para:
Formulários e validação
Injeção de dependência
Roteamento do lado do cliente
Layouts
Depuração no navegador
Interoperabilidade do JavaScript
Blazortem muito em comum com ASP.NET Web Forms. Ambas as estruturas oferecem modelos de programação
de interface do usuário com estado baseado em componente e orientados por eventos. A principal diferença
arquitetônica é que ASP.NET Web Forms é executado somente no servidor. Blazorpode ser executado no cliente no
navegador. Mas se você estiver vindo de uma ASP.NET Web Forms plano de fundo, há muita coisa Blazor que se
sentirá familiar. Blazoré uma solução natural para ASP.NET Web Forms desenvolvedores que buscam uma maneira
de aproveitar o desenvolvimento do lado do cliente e o futuro da plataforma cruzada de software livre do .NET.
Este livro fornece uma introdução ao Blazor que é fornecido especificamente para desenvolvedores de ASP.NET
Web Forms. Cada Blazor conceito é apresentado no contexto de Web Forms ASP.net análogos e recursos e práticas.
No final deste livro, você terá uma compreensão de:
Como criar Blazor aplicativos.
Como o Blazor funciona.
Como o Blazor se relaciona com o .NET Core.
Estratégias razoáveis para migrar os aplicativos ASP.NET Web Forms existentes para Blazor onde for
apropriado.

Introdução ao Blazor
A introdução ao Blazor é fácil. Vá para https://blazor.net e siga os links para instalar os modelos de projeto e SDK
do .NET Core apropriados Blazor . Você também encontrará instruções para configurar as Blazor ferramentas no
Visual Studio ou Visual Studio Code.

A N TE R IO R AVA N Ç A R
Comparação de arquitetura do ASP.NET Web Forms
eBlazor
24/07/2020 • 6 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Embora o ASP.NET Web Forms e Blazor tenha muitos conceitos semelhantes, há diferenças em como eles
funcionam. Este capítulo examina as arquiteturas e os trabalhos internos do ASP.NET Web Forms e Blazor .

Web Forms do ASP.NET


O ASP.NET Web Forms Framework se baseia em uma arquitetura centrada em página. Cada solicitação HTTP para
um local no aplicativo é uma página separada com a qual o ASP.NET responde. À medida que as páginas são
solicitadas, o conteúdo do navegador é substituído pelos resultados da página solicitada.
As páginas consistem nos seguintes componentes:
Marcação HTML
Código em C# ou Visual Basic
Uma classe code-behind que contém recursos de lógica e manipulação de eventos
Controles
Os controles são unidades reutilizáveis da interface do usuário da Web que podem ser colocadas e interagir de
forma programática em uma página. As páginas são compostas por arquivos que terminam com . aspx contendo
marcação, controles e algum código. As classes code-behind estão em arquivos com o mesmo nome base e uma
extensão . aspx.cs ou . aspx. vb , dependendo da linguagem de programação usada. Curiosamente, o servidor Web
interpreta o conteúdo dos arquivos . aspx e os compila sempre que eles forem alterados. Essa recompilação ocorre
mesmo que o servidor Web já esteja em execução.
Os controles podem ser criados com marcação e entregues como controles de usuário. Um controle de usuário
deriva da UserControl classe e tem uma estrutura semelhante à página. A marcação para controles de usuário é
armazenada em um arquivo . ascx . Uma classe code-behind acompanhante reside em um arquivo . ascx.cs ou .
ascx. vb . Os controles também podem ser compilados completamente com o código, herdando da WebControl
CompositeControl classe base ou.

As páginas também têm um ciclo de vida de eventos extensivo. Cada página gera eventos para os eventos de
inicialização, carregamento, PreRender e Unload que ocorrem quando o tempo de execução ASP.NET executa o
código da página para cada solicitação.
Os controles em uma página normalmente são postbacks para a mesma página que apresentou o controle e
transportam-se por uma carga de um campo de formulário oculto chamado ViewState . O ViewState campo
contém informações sobre o estado dos controles no momento em que eles foram renderizados e apresentados
na página, permitindo que o tempo de execução do ASP.net compare e identifique as alterações no conteúdo
enviado ao servidor.
Blazor
Blazoré uma estrutura de interface do usuário da Web do lado do cliente semelhante à natureza das estruturas de
front-end do JavaScript como angular ou reagir. Blazorlida com as interações do usuário e renderiza as
atualizações necessárias da interface do usuário. Blazornão é baseado em um modelo de solicitação-resposta. As
interações do usuário são tratadas como eventos que não estão no contexto de nenhuma solicitação HTTP
específica.
Blazoros aplicativos consistem em um ou mais componentes raiz que são processados em uma página HTML.

Como o usuário especifica onde os componentes devem renderizar e como os componentes são conectados para
interações de usuário é o modelo de hospedagem específico.
Blazoros componentes são classes .NET que representam uma parte reutilizável da interface do usuário. Cada
componente mantém seu próprio Estado e especifica sua própria lógica de renderização, que pode incluir a
renderização de outros componentes. Os componentes especificam manipuladores de eventos para interações
específicas do usuário para atualizar o estado do componente.
Depois que um componente manipula um evento, Blazor o renderiza o componente e controla o que foi alterado
na saída renderizada. Os componentes não são renderizados diretamente para o Modelo de Objeto do Documento
(DOM). Em vez disso, eles são renderizados em uma representação na memória do DOM chamado um
RenderTree para que Blazor possa rastrear as alterações. Blazorcompara a saída processada recentemente com a
saída anterior para calcular uma comparação de interface do usuário que é aplicada com eficiência ao DOM.
Os componentes também podem indicar manualmente que devem ser renderizados se seu estado for alterado
fora de um evento de interface do usuário normal. Blazorusa um SynchronizationContext para impor um único
thread lógico de execução. Os métodos de ciclo de vida de um componente e quaisquer retornos de chamada de
evento que são gerados por Blazor são executados nesse SynchronizationContext .

A N TE R IO R AVA N Ç A R
Blazormodelos de Hospedagem de aplicativo
24/07/2020 • 12 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Blazoros aplicativos podem ser hospedados no IIS, assim como ASP.NET Web Forms aplicativos. Blazoros
aplicativos também podem ser hospedados de uma das seguintes maneiras:
No lado do cliente no navegador em WebAssembly .
No lado do servidor em um aplicativo ASP.NET Core.

BlazorWebAssemblyaplicativos
BlazorWebAssemblyos aplicativos são executados diretamente no navegador em um WebAssembly tempo de
execução .net baseado em. Blazoros WebAssembly aplicativos funcionam de forma semelhante às estruturas
JavaScript de front-end, como angular ou reagir. No entanto, em vez de escrever JavaScript, você escreve C#. O
tempo de execução do .NET é baixado com o aplicativo junto com o assembly do aplicativo e as dependências
necessárias. Não são necessários plug-ins ou extensões de navegador.
Os assemblies baixados são assemblies normais do .NET, como você usaria em qualquer outro aplicativo .NET.
Como o tempo de execução dá suporte a .NET Standard, você pode usar bibliotecas de .NET Standard existentes
com seu Blazor WebAssembly aplicativo. No entanto, esses assemblies ainda serão executados na área restrita de
segurança do navegador. Algumas funcionalidades podem gerar um PlatformNotSupportedException , como
tentar acessar o sistema de arquivos ou abrir conexões de rede arbitrárias.
Quando o aplicativo é carregado, o tempo de execução do .NET é iniciado e apontado para o assembly do
aplicativo. A lógica de inicialização do aplicativo é executada e os componentes raiz são renderizados.
Blazorcalcula as atualizações da interface do usuário com base na saída renderizada dos componentes. As
atualizações do DOM são aplicadas.
Blazoros WebAssembly aplicativos executam puramente do lado do cliente. Esses aplicativos podem ser
implantados em soluções de Hospedagem de site estáticos, como páginas do GitHub ou Hospedagem de sites
estáticos do Azure. O .NET não é necessário no servidor. A vinculação profunda com partes do aplicativo
normalmente requer uma solução de roteamento no servidor. A solução de roteamento redireciona as
solicitações para a raiz do aplicativo. Por exemplo, esse redirecionamento pode ser tratado usando regras de
reescrita de URL no IIS.
Para obter todos os benefícios do Blazor desenvolvimento para a Web .net de pilha completa, hospede seu Blazor
WebAssembly aplicativo com ASP.NET Core. Usando o .NET no cliente e no servidor, você pode compartilhar
facilmente o código e criar seu aplicativo usando um conjunto consistente de linguagens, estruturas e
ferramentas. Blazorfornece modelos convenientes para configurar uma solução que contenha um Blazor
WebAssembly aplicativo e um projeto de host ASP.NET Core. Quando a solução é criada, os arquivos estáticos
internos do Blazor aplicativo são hospedados pelo aplicativo ASP.NET Core com o roteamento de fallback já
configurado.

BlazorAplicativos de servidor
Lembre-se da discussão sobre Blazor arquitetura que Blazor os componentes renderizam sua saída para uma
abstração intermediária chamada a RenderTree . BlazorEm seguida, a estrutura compara o que foi renderizado
com o que foi renderizado anteriormente. As diferenças são aplicadas ao DOM. Blazoros componentes são
dissociados de como a saída renderizada é aplicada. Consequentemente, os próprios componentes não precisam
ser executados no mesmo processo que o processo que atualiza a interface do usuário. Na verdade, eles nem
precisam ser executados no mesmo computador.
Em Blazor aplicativos de servidor, os componentes são executados no servidor em vez de no lado do cliente no
navegador. Os eventos de interface do usuário que ocorrem no navegador são enviados para o servidor em uma
conexão em tempo real. Os eventos são expedidos para as instâncias de componente corretas. Os componentes
são renderizados e a comparação de interface do usuário calculada é serializada e enviada ao navegador onde é
aplicada ao DOM.
O Blazor modelo de hospedagem do servidor pode parecer familiar se você usou o ASP.NET AJAX e o
UpdatePanel controle. O UpdatePanel controle manipula a aplicação de atualizações de página parcial em
resposta a eventos de gatilho na página. Quando disparado, o UpdatePanel solicita uma atualização parcial e, em
seguida, a aplica sem a necessidade de atualizar a página. O estado da interface do usuário é gerenciado usando
ViewState . BlazorOs aplicativos de servidor são ligeiramente diferentes, pois o aplicativo requer uma conexão
ativa com o cliente. Além disso, todo o estado da interface do usuário é mantido no servidor. Além dessas
diferenças, os dois modelos são conceitualmente semelhantes.

Como escolher o modelo de Blazor hospedagem correto


Conforme descrito nos Blazor documentos do modelo de hospedagem, os diferentes modelos de Blazor
hospedagem têm compensações diferentes.
O Blazor WebAssembly modelo de hospedagem tem os seguintes benefícios:
Não há nenhuma dependência do lado do servidor .NET. O aplicativo está totalmente funcionando depois de
baixado para o cliente.
Recursos e funcionalidades do cliente são totalmente aproveitados.
O trabalho é descarregado do servidor para o cliente.
Um servidor Web ASP.NET Core não é necessário para hospedar o aplicativo. Cenários de implantação sem
servidor são possíveis (por exemplo, servindo o aplicativo de uma CDN).
As desvantagens do modelo de Blazor WebAssembly hospedagem são:
Os recursos do navegador restringem o aplicativo.
O hardware e o software compatíveis do cliente (por exemplo, WebAssembly suporte) são necessários.
O tamanho do download é maior e os aplicativos demoram mais para serem carregados.
O suporte ao tempo de execução e às ferramentas do .NET é menos maduro. Por exemplo, há limitações no
suporte e na depuração de .net Standard .
Por outro lado, o Blazor modelo de Hospedagem de servidor oferece os seguintes benefícios:
O tamanho do download é muito menor do que um aplicativo do lado do cliente e o aplicativo é carregado
muito mais rapidamente.
O aplicativo aproveita totalmente os recursos do servidor, incluindo o uso de qualquer API compatível com o
.NET Core.
O .NET Core no servidor é usado para executar o aplicativo, portanto, as ferramentas .NET existentes, como
depuração, funcionam conforme o esperado.
Há suporte para clientes finos. Por exemplo, aplicativos do lado do servidor funcionam com navegadores que
não dão suporte a WebAssembly e em dispositivos com restrição de recursos.
A base de código .NET/C# do aplicativo, incluindo o código de componente do aplicativo, não é servida aos
clientes.
As desvantagens do modelo de Blazor hospedagem do servidor são:
Maior latência de interface do usuário. Cada interação do usuário envolve um salto de rede.
Não há suporte offline. Se a conexão do cliente falhar, o aplicativo para de funcionar.
A escalabilidade é desafiadora para aplicativos com muitos usuários. O servidor deve gerenciar várias
conexões de cliente e manipular o estado do cliente.
Um servidor de ASP.NET Core é necessário para atender ao aplicativo. Cenários de implantação sem servidor
não são possíveis. Por exemplo, você não pode servir o aplicativo de uma CDN.
A lista anterior de compensações pode ser intimidadora, mas seu modelo de hospedagem pode ser alterado
posteriormente. Independentemente do Blazor modelo de hospedagem selecionado, o modelo de componente é
o mesmo. Em princípio, os mesmos componentes podem ser usados com o modelo de hospedagem. O código do
aplicativo não é alterado; no entanto, é uma boa prática introduzir abstrações para que seus componentes fiquem
de hospedagem independente de modelo. As abstrações permitem que seu aplicativo adote com mais facilidade
um modelo de hospedagem diferente.

Implante seu aplicativo


Os aplicativos de Web Forms ASP.NET normalmente são hospedados no IIS em um computador ou cluster do
Windows Server. Blazoros aplicativos também podem:
Ser hospedado no IIS, seja como arquivos estáticos ou como um aplicativo ASP.NET Core.
Aproveite a flexibilidade de ASP.NET Core para ser hospedada em várias plataformas e infraestruturas de
servidor. Por exemplo, você pode hospedar um Blazor aplicativo usando Nginx ou Apache no Linux. Para obter
mais informações sobre como publicar e implantar Blazor aplicativos, consulte a Blazor documentação de
hospedagem e implantação .
Na próxima seção, veremos como os projetos para Blazor WebAssembly e os aplicativos de Blazor servidor são
configurados.

A N TE R IO R AVA N Ç A R
Estrutura do projeto para Blazor aplicativos
24/07/2020 • 17 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Apesar das diferenças significativas na estrutura do projeto, ASP.NET Web Forms e Blazor Compartilhe muitos
conceitos semelhantes. Aqui, veremos a estrutura de um Blazor projeto e o comparamos a um projeto ASP.NET
Web Forms.
Para criar seu primeiro Blazor aplicativo, siga as instruções nas Blazor etapas de introdução. Você pode seguir as
instruções para criar um Blazor aplicativo de servidor ou um Blazor WebAssembly aplicativo hospedado no
ASP.NET Core. Exceto para a lógica específica do modelo de hospedagem, a maior parte do código em ambos os
projetos é a mesma.

Arquivo de projeto
BlazorOs aplicativos de servidor são projetos .NET Core. O arquivo de projeto para o Blazor aplicativo de servidor
é quase tão simples quanto pode ser:

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

<PropertyGroup>
<TargetFramework>netcoreapp3.0</TargetFramework>
</PropertyGroup>

</Project>

O arquivo de projeto para um Blazor WebAssembly aplicativo parece um pouco mais envolvido (números de
versão exatas podem variar):
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RazorLangVersion>3.0</RazorLangVersion>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Blazor" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.Build" Version="3.1.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.HttpClient" Version="3.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Blazor.DevServer" Version="3.1.0" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Shared\BlazorWebAssemblyApp1.Shared.csproj" />
</ItemGroup>

</Project>

Blazoros WebAssembly projetos visam .net Standard em vez do .NET Core porque eles são executados no
navegador em um WebAssembly tempo de execução do .NET com base em um. Você não pode instalar o .NET em
um navegador da Web como você pode em um computador de servidor ou de desenvolvedor.
Consequentemente, o projeto faz referência à Blazor estrutura usando referências de pacote individuais.
Por comparação, um projeto ASP.NET Web Forms padrão inclui quase 300 linhas de XML em seu arquivo . csproj ,
a maior parte deles está listando explicitamente os vários arquivos de código e conteúdo no projeto. Muitas das
simplificações dos projetos baseados no .NET Core e no .NET Standard são provenientes dos destinos e das
propriedades padrão importadas referenciando o Microsoft.NET.Sdk.Web SDK, geralmente conhecido como
simplesmente o SDK da Web. O SDK da Web inclui curingas e outras conveniências que simplificam a inclusão de
código e arquivos de conteúdo no projeto. Você não precisa listar os arquivos explicitamente. Ao direcionar o .NET
Core, o Web SDK também adiciona referências de estrutura às estruturas compartilhadas do .NET Core e do
ASP.NET Core. As estruturas são visíveis no nó de estruturas de dependências > Frameworks na janela
Gerenciador de soluções . As estruturas compartilhadas são coleções de assemblies que foram instalados no
computador durante a instalação do .NET Core.
Embora eles tenham suporte, as referências de assembly individuais são menos comuns em projetos do .NET
Core. A maioria das dependências do projeto é tratada como referências de pacote NuGet. Você só precisa
referenciar as dependências de pacote de nível superior em projetos do .NET Core. Dependências transitivas são
incluídas automaticamente. Em vez de usar o arquivo de packages.config normalmente encontrado em projetos
de Web Forms de ASP.net para referenciar pacotes, as referências de pacote são adicionadas ao arquivo de projeto
usando o <PackageReference> elemento.

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

Ponto de entrada
O Blazor ponto de entrada do aplicativo de 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 Web usando
padrões específicos para aplicativos Web. O host da Web gerencia o Blazor ciclo de vida do aplicativo do servidor
e configura os serviços de nível de host. Exemplos desses serviços são configuração, registro em log, injeção de
dependência e o servidor HTTP. Esse código é basicamente clichê e, muitas vezes, permanece inalterado.
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}

public static IHostBuilder CreateHostBuilder(string[] args) =>


Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}

Blazoros WebAssembly aplicativos também definem um ponto de entrada em Program.cs. O código parece um
pouco diferente. O código é semelhante, pois está configurando o host de aplicativo para fornecer os mesmos
serviços de nível de host para o aplicativo. WebAssemblyNo entanto, o host de aplicativo não configura um
servidor http porque ele é executado diretamente no navegador.
Blazoros aplicativos têm uma Startup classe em vez de um arquivo global. asax para definir a lógica de
inicialização para o aplicativo. A Startup classe é usada para configurar o aplicativo e quaisquer serviços
específicos do aplicativo. No Blazor aplicativo de servidor, a Startup classe é usada para configurar o ponto de
extremidade para a conexão em tempo real usada pelo Blazor entre os navegadores cliente e o servidor. No Blazor
WebAssembly aplicativo, a Startup classe define os componentes raiz para o aplicativo e onde eles devem ser
renderizados. Vamos dar uma olhada mais detalhada na Startup classe na seção de inicialização do aplicativo .

Arquivos estáticos
Ao contrário dos projetos do ASP.NET 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 da Web. Essa pasta
é referida na "raiz da Web" do aplicativo. Qualquer coisa fora da raiz da Web do aplicativo não é endereçável da
Web. Essa configuração fornece um nível adicional de segurança que impede a exposição acidental de arquivos de
projeto na Web.

Configuração
A configuração no ASP.NET Web Forms aplicativos normalmente é manipulada usando um ou mais arquivos de
web.config . Blazoros aplicativos normalmente não têm web.config arquivos. Se isso for feito, o arquivo será usado
apenas 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 ( Blazor WebAssembly os aplicativos atualmente
não dão suporte às mesmas abstrações de configuração, mas podem ser um recurso adicionado no futuro). Por
exemplo, o Blazor aplicativo de servidor padrão armazena algumas configurações no appsettings.jsem.

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

Aprenderemos mais sobre a configuração em projetos ASP.NET Core na seção de configuração .


Componentes do Razor
A maioria dos arquivos em Blazor projetos são arquivos . Razor . O Razor é uma linguagem de modelagem
baseada em HTML e em 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. Para a maior parte, os
componentes são idênticos para o Blazor servidor e os Blazor WebAssembly aplicativos. Os componentes no
Blazor são análogos aos controles de usuário no ASP.NET Web Forms.
Cada arquivo de componente do Razor é compilado em uma classe do .NET quando o projeto é compilado. A
classe gerada captura o estado do componente, a lógica de renderização, os métodos de ciclo de vida, os
manipuladores de eventos e outras lógicas. Vamos examinar os componentes de criação na seção criando
componentes Blazor de interface do usuário reutilizáveis .
Os arquivos _Imports. Razor não são arquivos de componente do Razor. Em vez disso, eles definem um conjunto
de diretivas do 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 Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Components.Authorization
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.JSInterop
@using BlazorApp1
@using BlazorApp1.Shared

Páginas
Onde estão as páginas nos Blazor aplicativos? Blazornão define uma extensão de arquivo separada para páginas
endereçáveis, como os arquivos . aspx em ASP.NET Web Forms aplicativos. Em vez disso, as páginas são definidas
por meio da atribuição de rotas a 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 no Blazor é tratado pelo lado do cliente, não no servidor. À medida que o usuário navega no
navegador, Blazor intercepta a navegação e, em seguida, renderiza o componente com a rota correspondente.
As rotas de componentes não são inferidas no momento pelo local do arquivo do componente como estão com
páginas . aspx . Esse recurso pode ser adicionado no futuro. Cada rota deve ser especificada explicitamente no
componente. O armazenamento de componentes roteáveis em uma pasta de páginas não tem significado especial
e é puramente uma convenção.
Veremos mais detalhadamente no roteamento no Blazor na seção páginas, roteamento e layouts .

Layout
No ASP.NET Web Forms aplicativos, o layout de página comum é manipulado usando páginas mestras (site.
Master). Em Blazor aplicativos, o layout de página é manipulado usando componentes de layout
(Shared/MainLayout. Razor). Os componentes de layout serão discutidos em mais detalhes na seção página,
roteamento e layouts .
InicializaçãoBlazor
Para inicializar Blazor , o aplicativo deve:
Especifique o local na página em que o componente raiz (app. Razor) deve ser renderizado.
Adicione o Blazor script de estrutura correspondente.
No Blazor aplicativo de servidor, a página host do componente raiz é definida no arquivo _Host. cshtml . Esse
arquivo define uma página Razor, não um componente. Razor Pages usar sintaxe Razor para definir uma página
endereçável do servidor, muito parecida com uma página . aspx . O
Html.RenderComponentAsync<TComponent>(RenderMode) método é usado para definir onde um componente de nível
raiz deve ser renderizado. A RenderMode opção indica a maneira como o componente deve ser renderizado. A
tabela a seguir descreve as opções com suporte RenderMode .

OPÇ ÃO DESC RIÇ Ã O

RenderMode.Server Renderizado interativamente quando uma conexão com o


navegador é estabelecida

RenderMode.ServerPrerendered Primeiro renderizado e, em seguida, renderizado


interativamente

RenderMode.Static Renderizado como conteúdo estático

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 as atualizações da interface de usuário.

@page "/"
@namespace BlazorApp1.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" />
<title>BlazorApp1</title>
<base href="~/" />
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<app>
@(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>

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

No Blazor WebAssembly aplicativo, a página host é um arquivo HTML estático simples em wwwroot/index.html. O
<app> elemento é usado para indicar onde o componente raiz deve ser renderizado.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>BlazorApp2</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>

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

O componente específico a ser renderizado é configurado no método do aplicativo Startup.Configure com um


seletor CSS correspondente, indicando onde o componente deve ser renderizado.

public class Startup


{
public void ConfigureServices(IServiceCollection services)
{
}

public void Configure(IComponentsApplicationBuilder app)


{
app.AddComponent<App>("app");
}
}

Saída do build
Quando um Blazor projeto é compilado, todos os arquivos de código e componente do Razor são compilados em
um único assembly. Diferentemente do ASP.NET Web Forms projetos, Blazor o não dá suporte à compilação em
tempo de execução da lógica da interface do usuário

Executar o aplicativo
Para executar o Blazor aplicativo de servidor, pressione F5 no Visual Studio. Blazoros aplicativos não oferecem
suporte à compilação em tempo de execução. Para ver os resultados das alterações de marcação de código e de
componente, recompile e reinicie o aplicativo com o depurador anexado. Se você executar sem o depurador
anexado ( Ctrl+F5 ), o Visual Studio inspecionará as alterações de arquivo e reiniciará o aplicativo conforme as
alterações forem feitas. Você atualiza manualmente o navegador conforme as alterações são feitas.
Para executar o Blazor WebAssembly aplicativo, escolha uma das seguintes abordagens:
Execute o projeto do cliente diretamente usando o servidor de desenvolvimento.
Execute o projeto de servidor ao hospedar o aplicativo com ASP.NET Core.
Blazoros WebAssembly aplicativos não oferecem suporte à depuração usando o Visual Studio. Para executar o
aplicativo, use Ctrl+F5 em vez de F5 . Em vez disso, você pode depurar Blazor WebAssembly aplicativos
diretamente no navegador. Consulte depurar ASP.NET Core Blazor para obter detalhes.

A N TE R IO R AVA N Ç A R
Inicialização do aplicativo
23/11/2019 • 2 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Esse conteúdo será disponibilizado em breve.

A N TE R IO R PR Ó XIM O
Crie componentes da interface do usuário
reutilizáveis comBlazor
24/07/2020 • 30 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Uma das belas coisas sobre o ASP.NET Web Forms é como ela permite o encapsulamento de partes reutilizáveis
do código da interface do usuário em controles de interface de usuários reutilizáveis. Os controles de usuário
personalizados podem ser definidos na marcação usando arquivos . ascx . Você também pode criar controles de
servidor elaborados em código com suporte completo ao designer.
Blazortambém dá suporte ao encapsulamento de interface do usuário por meio de componentes. Um
componente:
É uma parte independente da interface do usuário.
Mantém seu próprio Estado e lógica de renderização.
Pode definir manipuladores de eventos de interface do usuário, associar a dados de entrada e gerenciar seu
próprio ciclo de vida.
Normalmente é definido em um arquivo . Razor usando sintaxe Razor.

Uma introdução ao Razor


O Razor é uma linguagem de modelagem de marcação leve com base em HTML e em C#. Com o Razor, você
pode fazer a transição diretamente entre marcação e código C# para definir a lógica de renderização do
componente. Quando o arquivo . Razor é compilado, a lógica de renderização é capturada de forma estruturada
em uma classe do .net. O nome da classe compilada é extraído do nome do arquivo . Razor . O namespace é
extraído do namespace padrão para o projeto e o caminho da pasta, ou você pode especificar explicitamente o
namespace usando a @namespace diretiva (mais sobre as diretivas do Razor abaixo).
A lógica de renderização de um componente é criada usando marcação HTML normal com lógica dinâmica
adicionada usando C#. O @ caractere é usado para fazer a transição para C#. O Razor normalmente é inteligente
para descobrir quando você volta para o HTML. Por exemplo, o componente a seguir renderiza uma <p> marca
com a hora atual:

<p>@DateTime.Now</p>

Para especificar explicitamente o início e o final de uma expressão C#, use parênteses:

<p>@(DateTime.Now)</p>

O Razor também facilita o uso do fluxo de controle C# na lógica de renderização. Por exemplo, você pode
renderizar condicionalmente um HTML como este:
@if (value % 2 == 0)
{
<p>The value was even.</p>
}

Ou você pode gerar uma lista de itens usando um loop C# normal foreach como este:

<ul>
@foreach (var item in items)
{
<li>@item.Text</li>
}
</ul>

As diretivas do Razor, como diretivas no ASP.NET Web Forms, controlam muitos aspectos de como um
componente Razor é compilado. Os exemplos incluem o componente:
Namespace
Classe base
Interfaces implementadas
Parâmetros genéricos
Namespaces importados
Rotas
As diretivas do Razor começam com o @ caractere e normalmente são usadas no início de uma nova linha no
início do arquivo. Por exemplo, a @namespace diretiva define o namespace do componente:

@namespace MyComponentNamespace

A tabela a seguir resume as várias diretivas do Razor usadas no Blazor e suas ASP.NET Web Forms equivalentes,
se existirem.

DIRET IVA DESC RIÇ Ã O EXEM P LO W EB F O RM S EQ UIVA L EN T E

@attribute Adiciona um atributo de @attribute [Authorize] Nenhum


nível de classe ao
componente

@code Adiciona membros de classe @code { ... } <script


ao componente runat="server">...
</script>

@implements Implementa a interface @implements IDisposable Usar code-behind


especificada

@inherits Herda da classe base @inherits <%@ Control


especificada MyComponentBase Inherits="MyUserControlBase"
%>

@inject Injeta um serviço no @inject IJSRuntime JS Nenhum


componente

@layout Especifica um componente @layout MainLayout <%@ Page


de layout para o MasterPageFile="~/Site.Master"
%>
componente
DIRET IVA DESC RIÇ Ã O EXEM P LO W EB F O RM S EQ UIVA L EN T E

@namespace Define o namespace para o @namespace MyNamespace Nenhum


componente

@page Especifica a rota para o @page "/product/{id}" <%@ Page %>


componente

@typeparam Especifica um parâmetro de @typeparam TItem Usar code-behind


tipo genérico para o
componente

@using Especifica um namespace @using Adicionar namespace no


para trazer para o escopo MyComponentNamespace web.config

Os componentes do Razor também fazem uso extensivo de atributos de diretiva em elementos para controlar
vários aspectos de como os componentes são compilados (manipulação de eventos, vinculação de dados,
referências de elementos de & de componentes e assim por diante). Atributos de diretiva seguem uma sintaxe
genérica comum em que os valores entre parênteses são opcionais:

@directive(-suffix(:name))(="value")

A tabela a seguir resume os vários atributos para as diretivas do Razor usadas no Blazor .

AT RIB UTO DESC RIÇ Ã O EXEM P LO

@attributes Renderiza um dicionário de atributos <input


@attributes="ExtraAttributes" />

@bind Cria uma associação de dados <input @bind="username"


bidirecional @bind:event="oninput" />

@on{event} Adiciona um manipulador de eventos <button


para o evento especificado @onclick="IncrementCount">Click
me!</button>

@key Especifica uma chave a ser usada pelo <DetailsEditor @key="person"


algoritmo diff para preservar elementos Details="person.Details" />
em uma coleção

@ref Captura uma referência para o <MyDialog @ref="myDialog" />


componente ou elemento HTML

Os vários atributos de diretiva usados pelo Blazor ( @onclick ,, @bind @ref e assim por diante) são abordados
nas seções abaixo e nos capítulos posteriores.
Muitas das sintaxes usadas em arquivos . aspx e . ascx têm sintaxes paralelas no Razor. Veja abaixo uma
comparação simples das sintaxes para ASP.NET Web Forms e Razor.

REC URSO W EB F O RM S SY N TA X RA Z O R SY N TA X

Diretivas <%@ [directive] <%@ Page %> @[directive] @page


%>
REC URSO W EB F O RM S SY N TA X RA Z O R SY N TA X

Blocos de códigos <% %> <% int x = 123; @{ } @{ int x = 123; }


%>

Expressões <%: %> <%:DateTime.Now Localiza @ @DateTime.Now


(Codificado em %> Explicita @() @(DateTime.Now)
HTML)

Comentários <%-- --%> <%-- Commented -- @* *@ @* Commented *@


%>

Associação de dados <%# %> <%# Bind("Name") @bind <input


%> @bind="username"
/>

Para adicionar membros à classe de componente Razor, use a @code diretiva. Essa técnica é semelhante ao uso
de um <script runat="server">...</script> bloco em um ASP.NET Web Forms controle de usuário ou página.

@code {
int count = 0;

void IncrementCount()
{
count++;
}
}

Como o Razor se baseia em C#, ele deve ser compilado de dentro de um projeto C# (. csproj). Não é possível
compilar arquivos . Razor de um projeto Visual Basic (. vbproj). Você ainda pode fazer referência a projetos Visual
Basic do seu Blazor projeto. O oposto também é verdadeiro.
Para obter uma referência completa de sintaxe Razor, consulte referência de sintaxe Razor para ASP.NET Core.

Usar componentes
Além do HTML normal, os componentes também podem usar outros componentes como parte da lógica de
renderização. A sintaxe para usar um componente no Razor é semelhante ao uso de um controle de usuário em
um aplicativo ASP.NET Web Forms. Os componentes são especificados usando uma marca de elemento que
corresponde ao nome do tipo do componente. Por exemplo, você pode adicionar um Counter componente como
este:

<Counter />

Ao contrário de ASP.NET Web Forms, os componentes em Blazor :


Não use um prefixo de elemento (por exemplo, asp: ).
Não exija o registro na página ou no web.config.
Imagine os componentes do Razor como você faria com os tipos do .NET, pois isso é exatamente o que eles são.
Se o assembly que contém o componente for referenciado, o componente estará disponível para uso. Para
colocar o namespace do componente no escopo, aplique a @using diretiva:
@using MyComponentLib

<Counter />

Como visto nos projetos padrão Blazor , é comum colocar @using diretivas em um arquivo _Imports. Razor para
que eles sejam importados para todos os arquivos . Razor no mesmo diretório e em diretórios filho.
Se o namespace de um componente não estiver no escopo, você poderá especificar um componente usando seu
nome de tipo completo, como você pode em C#:

<MyComponentLib.Counter />

Parâmetros do componente
No ASP.NET Web Forms, você pode fluir parâmetros e dados para controles usando propriedades públicas. Essas
propriedades podem ser definidas na marcação usando atributos ou definidos diretamente no código. Blazoros
componentes funcionam de maneira semelhante, embora as propriedades do componente também devam ser
marcadas com o [Parameter] atributo para serem considerados parâmetros de componente.
O componente a seguir Counter define um parâmetro de componente chamado IncrementAmount que pode ser
usado para especificar a quantidade que Counter deve ser incrementada toda vez que o botão é clicado.

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {
int currentCount = 0;

[Parameter]
public int IncrementAmount { get; set; } = 1;

void IncrementCount()
{
currentCount+=IncrementAmount;
}
}

Para especificar um parâmetro de componente no Blazor , use um atributo como você faria em ASP.NET Web
Forms:

<Counter IncrementAmount="10" />

Manipuladores de eventos
ASP.NET Web Forms e Blazor fornecem um modelo de programação baseado em eventos para manipular
eventos de interface do usuário. Exemplos desses eventos incluem cliques de botão e entrada de texto. No
ASP.NET Web Forms, você usa controles de servidor HTML para manipular eventos de interface do usuário
expostos pelo DOM ou pode manipular eventos expostos por controles de servidor Web. Os eventos são exibidos
no servidor por meio de solicitações de postback de formulário. Considere o seguinte Web Forms exemplo de
clique de botão:
Counter. ascx
<asp:Button ID="ClickMeButton" runat="server" Text="Click me!" OnClick="ClickMeButton_Click" />

Counter.ascx.cs

public partial class Counter : System.Web.UI.UserControl


{
protected void ClickMeButton_Click(object sender, EventArgs e)
{
Console.WriteLine("The button was clicked!");
}
}

No Blazor , você pode registrar manipuladores para eventos da interface do usuário dom diretamente usando
atributos de diretiva do formulário @on{event} . O {event} espaço reservado representa o nome do evento. Por
exemplo, você pode ouvir cliques de botão como este:

<button @onclick="OnClick">Click me!</button>

@code {
void OnClick()
{
Console.WriteLine("The button was clicked!);
}
}

Os manipuladores de eventos podem aceitar um argumento opcional, específico do evento, para fornecer mais
informações sobre o evento. Por exemplo, eventos de mouse podem usar um MouseEventArgs argumento, mas
não é necessário.

<button @onclick="OnClick">Click me!</button>

@code {
void OnClick(MouseEventArgs e)
{
Console.WriteLine($"Mouse clicked at {e.ScreenX}, {e.ScreenY}.");
}
}

Em vez de fazer referência a um grupo de métodos para um manipulador de eventos, você pode usar uma
expressão lambda. Uma expressão lambda permite que você feche outros valores no escopo.

@foreach (var buttonLabel in buttonLabels)


{
<button @onclick="() => Console.WriteLine($"The {buttonLabel} button was
clicked!")">@buttonLabel</button>
}

Os manipuladores de eventos podem ser executados de forma síncrona ou assíncrona. Por exemplo, o seguinte
OnClick manipulador de eventos é executado de forma assíncrona:
<button @onclick="OnClick">Click me!</button>

@code {
async Task OnClick()
{
var result = await Http.GetAsync("api/values");
}
}

Depois que um evento é manipulado, o componente é renderizado para considerar qualquer alteração de estado
de componente. Com manipuladores de eventos assíncronos, o componente é renderizado imediatamente após a
execução do manipulador ser concluída. O componente é renderizado novamente após a Task conclusão da
Asynchronous. Esse modo de execução assíncrono fornece uma oportunidade de renderizar alguma interface do
usuário apropriada enquanto o assíncrono Task ainda está em andamento.

<button @onclick="ShowMessage">Get message</button>

@if (showMessage)
{
@if (message == null)
{
<p><em>Loading...</em></p>
}
else
{
<p>The message is: @message</p>
}
}

@code
{
bool showMessage = false;
string message;

public async Task ShowMessage()


{
showMessage = true;
message = await MessageService.GetMessageAsync();
}
}

Os componentes também podem definir seus próprios eventos definindo um parâmetro de componente do tipo
EventCallback<TValue> . Os retornos de chamada de evento dão suporte a todas as variações de manipuladores
de eventos de interface do usuário DOM: argumentos opcionais, síncronos ou assíncronos, grupos de métodos
ou expressões lambda.

<button class="btn btn-primary" @onclick="OnClick">Click me!</button>

@code {
[Parameter]
public EventCallback<MouseEventArgs> OnClick { get; set; }
}

Associação de dados
Blazorfornece um mecanismo simples para associar dados de um componente de interface do usuário ao estado
do componente. Essa abordagem difere dos recursos do ASP.NET Web Forms para associação de dados de fontes
de dados a controles de interface do usuário. Abordaremos o tratamento de dados de fontes de dados diferentes
na seção lidando com dados .
Para criar uma associação de dados bidirecional de um componente de interface do usuário para o estado do
componente, use o @bind atributo de diretiva. No exemplo a seguir, o valor da caixa de seleção é associado ao
isChecked campo.

<input type="checkbox" @bind="isChecked" />

@code {
bool isChecked;
}

Quando o componente é renderizado, o valor da caixa de seleção é definido como o valor do isChecked campo.
Quando o usuário alterna a caixa de seleção, o onchange evento é acionado e o isChecked campo é definido para
o novo valor. A @bind sintaxe, nesse caso, é equivalente à seguinte marcação:

<input value="@isChecked" @onchange="(UIChangeEventArgs e) => isChecked = e.Value" />

Para alterar o evento usado para a associação, use o @bind:event atributo.

<input @bind="text" @bind:event="oninput" />


<p>@text</p>

@code {
string text;
}

Os componentes também podem dar suporte à ligação de dados com seus parâmetros. Para associação de
dados, defina um parâmetro de retorno de chamada de evento com o mesmo nome que o parâmetro acoplável.
O sufixo "alterado" é adicionado ao nome.
PasswordBox. Razor

Password: <input
value="@Password"
@oninput="OnPasswordChanged"
type="@(showPassword ? "text" : "password")" />

<label><input type="checkbox" @bind="showPassword" />Show password</label>

@code {
private bool showPassword;

[Parameter]
public string Password { get; set; }

[Parameter]
public EventCallback<string> PasswordChanged { get; set; }

private Task OnPasswordChanged(ChangeEventArgs e)


{
Password = e.Value.ToString();
return PasswordChanged.InvokeAsync(Password);
}
}

Para encadear uma associação de dados a um elemento subjacente da interface do usuário, defina o valor e
manipule o evento diretamente no elemento da interface do usuário em vez de usar o @bind atributo.
Para associar a um parâmetro de componente, use um @bind-{Parameter} atributo para especificar o parâmetro
ao qual você deseja associar.

<PasswordBox @bind-Password="password" />

@code {
string password;
}

Alterações de estado
Se o estado do componente foi alterado fora de um evento de interface do usuário normal ou de retorno de
chamada de evento, o componente deve sinalizar manualmente que ele precisa ser processado novamente. Para
sinalizar que o estado de um componente foi alterado, chame o StateHasChanged método no componente.
No exemplo a seguir, um componente exibe uma mensagem de um AppState serviço que pode ser atualizado
por outras partes do aplicativo. O componente registra seu StateHasChanged método com o AppState.OnChange
evento para que o componente seja renderizado sempre que a mensagem for atualizada.

public class AppState


{
public string Message { get; }

// Lets components receive change notifications


public event Action OnChange;

public void UpdateMessage(string message)


{
Message = message;
NotifyStateChanged();
}

private void NotifyStateChanged() => OnChange?.Invoke();


}

@inject AppState AppState

<p>App message: @AppState.Message</p>

@code {
protected override void OnInitialized()
{
AppState.OnChange += StateHasChanged
}
}

Ciclo de vida do componente


O ASP.NET Web Forms Framework tem métodos de ciclo de vida bem definidos para módulos, páginas e
controles. Por exemplo, o controle a seguir implementa manipuladores de eventos para os Init Load eventos
de ciclo de vida, e UnLoad :
Counter.ascx.cs
public partial class Counter : System.Web.UI.UserControl
{
protected void Page_Init(object sender, EventArgs e) { ... }
protected void Page_Load(object sender, EventArgs e) { ... }
protected void Page_UnLoad(object sender, EventArgs e) { ... }
}

Blazoros componentes também têm um ciclo de vida bem definido. O ciclo de vida de um componente pode ser
usado para inicializar o estado do componente e implementar comportamentos avançados de componentes.
Todos os Blazor métodos de ciclo de vida do componente têm versões síncronas e assíncronas. A renderização do
componente é síncrona. Não é possível executar a lógica assíncrona como parte da renderização do componente.
Toda a lógica assíncrona deve ser executada como parte de um async método de ciclo de vida.
OnInitialized
Os OnInitialized OnInitializedAsync métodos e são usados para inicializar o componente. Um componente é
normalmente inicializado após sua primeira renderização. Depois que um componente é inicializado, ele pode ser
renderizado várias vezes antes de ser Descartado. O OnInitialized método é semelhante ao Page_Load evento
no ASP.NET Web Forms páginas e controles.

protected override void OnInitialized() { ... }


protected override async Task OnInitializedAsync() { await ... }

Parameterset
Os OnParametersSet OnParametersSetAsync métodos e são chamados quando um componente recebe
parâmetros de seu pai e o valor é atribuído a propriedades. Esses métodos são executados após a inicialização do
componente e cada vez que o componente é renderizado.

protected override void OnParametersSet() { ... }


protected override async Task OnParametersSetAsync() { await ... }

OnAfterRender
Os OnAfterRender OnAfterRenderAsync métodos e são chamados após a conclusão da renderização de um
componente. Referências de elemento e componente são preenchidas neste ponto (mais sobre esses conceitos
abaixo). A interatividade com o navegador está habilitada neste ponto. As interações com a execução do DOM e
do JavaScript podem ocorrer com segurança.

protected override void OnAfterRender(bool firstRender)


{
if (firstRender)
{
...
}
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await ...
}
}

OnAfterRender e OnAfterRenderAsync não são chamados durante o pré-processamento no servidor.


O firstRender parâmetro é true a primeira vez que o componente é renderizado; caso contrário, seu valor é
false .
IDisposable
Blazoros componentes podem IDisposable ser implementados para descartar recursos quando o componente é
removido da interface do usuário. Um componente Razor pode implementar IDispose usando a @implements
diretiva:

@using System
@implements IDisposable

...

@code {
public void Dispose()
{
...
}
}

Capturar referências de componente


No ASP.NET Web Forms, é comum manipular uma instância de controle diretamente no código, referindo-se à
sua ID. No Blazor , também é possível capturar e manipular uma referência a um componente, embora seja muito
menos comum.
Para capturar uma referência de componente no Blazor , use o @ref atributo de diretiva. O valor do atributo
deve corresponder ao nome de um campo configurável com o mesmo tipo do componente referenciado.

<MyLoginDialog @ref="loginDialog" ... />

@code {
MyLoginDialog loginDialog;

void OnSomething()
{
loginDialog.Show();
}
}

Quando o componente pai é renderizado, o campo é populado com a instância de componente filho. Em seguida,
você pode chamar métodos em, ou então manipular, a instância do componente.
Não é recomendável manipular o estado do componente diretamente usando referências de componente. Isso
impede que o componente seja renderizado automaticamente nos horários corretos.

Capturar referências de elemento


Blazoros componentes do podem capturar referências a um elemento. Ao contrário dos controles de servidor
HTML no ASP.NET Web Forms, você não pode manipular o DOM diretamente usando uma referência de
elemento no Blazor . Blazorlida com a maioria das interações de DOM para você usando seu algoritmo de
comparação DOM. Referências de elemento capturado no Blazor são opacas. No entanto, eles são usados para
passar uma referência de elemento específica em uma chamada de interoperabilidade JavaScript. Para obter mais
informações sobre a interoperabilidade de JavaScript, consulte ASP.NET Core Blazor interoperabilidade de
JavaScript.

Componentes modelados
No ASP.NET Web Forms, você pode criar controles modelo. Controles de modelo permitem que o desenvolvedor
especifique uma parte do HTML usada para renderizar um controle de contêiner. A mecânica da criação de
controles de servidor modelo é complexa, mas permite cenários poderosos para a renderização de dados em
uma maneira personalizável do usuário. Exemplos de controles de modelo incluem Repeater e DataList .
Blazoros componentes também podem ser modelados definindo parâmetros de componente do tipo
RenderFragment ou RenderFragment<T> . Um RenderFragment representa uma parte da marcação Razor que pode
ser renderizada pelo componente. Um RenderFragment<T> é uma parte da marcação Razor que usa um
parâmetro que pode ser especificado quando o fragmento de renderização é renderizado.
Conteúdo filho
Blazoros componentes podem capturar seu conteúdo filho como um RenderFragment e renderizar esse conteúdo
como parte da renderização do componente. Para capturar o conteúdo filho, defina um parâmetro de
componente do tipo RenderFragment e nomeie-o ChildContent .
ChildContentComponent. Razor

<h1>Component with child content</h1>

<div>@ChildContent</div>

@code {
[Parameter]
public RenderFragment ChildContent { get; set; }
}

Um componente pai pode fornecer conteúdo filho usando sintaxe Razor normal.

<ChildContentComponent>
<p>The time is @DateTime.Now</p>
</ChildContentComponent>

Parâmetros de modelo
Um componente modelo Blazor também pode definir vários parâmetros de componente do tipo RenderFragment
ou RenderFragment<T> . O parâmetro para um RenderFragment<T> pode ser especificado quando é invocado. Para
especificar um parâmetro de tipo genérico para um componente, use a @typeparam diretiva Razor.
SimpleListView. Razor
@typeparam TItem

@Heading

<ul>
@foreach (var item in Items)
{
<li>@ItemTemplate(item)</li>
}
</ul>

@code {
[Parameter]
public RenderFragment Heading { get; set; }

[Parameter]
public RenderFragment<TItem> ItemTemplate { get; set; }

[Parameter]
public IEnumerable<TItem> Items { get; set; }
}

Ao usar um componente modelo, os parâmetros do modelo podem ser especificados usando elementos filho que
correspondem aos nomes dos parâmetros. Argumentos de componente do tipo RenderFragment<T> passado
como elementos têm um parâmetro implícito denominado context . Você pode alterar o nome desse parâmetro
de implementação usando o Context atributo no elemento filho. Qualquer parâmetro de tipo genérico pode ser
especificado usando um atributo que corresponde ao nome do parâmetro de tipo. O parâmetro de tipo será
inferido se possível:

<SimpleListView Items="messages" TItem="string">


<Heading>
<h1>My list</h1>
</Heading>
<ItemTemplate Context="message">
<p>The message is: @message</p>
</ItemTemplate>
</SimpleListView>

A saída desse componente tem esta aparência:

<h1>My list</h1>
<ul>
<li><p>The message is: message1</p></li>
<li><p>The message is: message2</p></li>
<ul>

Code-behind
Normalmente, um Blazor componente é criado em um único arquivo . Razor . No entanto, também é possível
separar o código e a marcação usando um arquivo code-behind. Para usar um arquivo de componente, adicione
um arquivo C# que corresponda ao nome do arquivo do componente, mas com uma extensão . cs adicionada
(Counter.Razor.cs). Use o arquivo C# para definir uma classe base para o componente. Você pode nomear a classe
base como quiser, mas é comum nomear a classe da mesma forma que a classe de componente, mas com uma
Base extensão adicionada ( CounterBase ). A classe baseada em componente também deve derivar de
ComponentBase . Em seguida, no arquivo de componente Razor, adicione a @inherits diretiva para especificar a
classe base para o componente ( @inherits CounterBase ).
Counter. Razor
@inherits CounterBase

<h1>Counter</h1>

<p>Current count: @currentCount</p>

<button @onclick="IncrementCount">Click me</button>

Counter.razor.cs

public class CounterBase : ComponentBase


{
protected int currentCount = 0;

protected void IncrementCount()


{
currentCount++;
}
}

A visibilidade dos membros do componente na classe base deve ser protected ou public estar visível para a
classe de componente.

Recursos adicionais
O anterior não é um tratamento completo de todos os aspectos dos Blazor componentes. Para obter mais
informações sobre como criar e usar ASP.NET Core componentes do Razor, consulte a Blazor documentação.

A N TE R IO R AVA N Ç A R
Páginas, roteamento e layouts
24/07/2020 • 12 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

ASP.NET Web Forms aplicativos são compostos de páginas definidas em arquivos . aspx . O endereço de cada
página é baseado em seu caminho de arquivo físico no projeto. Quando um navegador faz uma solicitação para
a página, o conteúdo da página é processado dinamicamente no servidor. As contas de renderização para a
marcação HTML da página e seus controles de servidor.
No Blazor , cada página no aplicativo é um componente, normalmente definido em um arquivo . Razor , com
uma ou mais rotas especificadas. O roteamento ocorre principalmente no lado do cliente sem envolver uma
solicitação de servidor específica. O navegador primeiro faz uma solicitação para o endereço raiz do aplicativo.
Um Router componente raiz no Blazor aplicativo, em seguida, lida com a interceptação de solicitações de
navegação e com o componente correto.
Blazortambém dá suporte à vinculação profunda. A vinculação profunda ocorre quando o navegador faz uma
solicitação para uma rota específica diferente da raiz do aplicativo. As solicitações de links profundos enviados ao
servidor são roteadas para o Blazor aplicativo, que roteia a solicitação do lado do cliente para o componente
correto.
Uma página simples no ASP.NET Web Forms pode conter a seguinte marcação:
Name. aspx

<%@ Page Title="Name" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"


CodeBehind="Name.aspx.cs" Inherits="WebApplication1.Name" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">


<div>
What is your name?<br />
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
</div>
<div>
<asp:Literal ID="Literal1" runat="server" />
</div>
</asp:Content>

Name.aspx.cs

public partial class Name : System.Web.UI.Page


{
protected void Button1_Click1(object sender, EventArgs e)
{
Literal1.Text = "Hello " + TextBox1.Text;
}
}
A página equivalente em um Blazor aplicativo ficaria assim:
Nome. Razor

@page "/Name"
@layout MainLayout

<div>
What is your name?<br />
<input @bind="text" />
<button @onclick="OnClick">Submit</button>
</div>
<div>
@if (name != null)
{
@:Hello @name
}
</div>

@code {
string text;
string name;

void OnClick() {
name = text;
}
}

Criar páginas
Para criar uma página no Blazor , crie um componente e adicione a @page diretiva Razor para especificar a rota
para o componente. A @page diretiva usa um único parâmetro, que é o modelo de rota a ser adicionado a esse
componente.

@page "/counter"

O parâmetro de modelo de rota é necessário. Ao contrário de ASP.NET Web Forms, a rota para um Blazor
componente não é inferida de seu local de arquivo (embora isso possa ser um recurso adicionado no futuro).
A sintaxe do modelo de rota é a mesma sintaxe básica usada para roteamento no ASP.NET Web Forms. Os
parâmetros de rota são especificados no modelo usando chaves. Blazorassociará valores de rota a parâmetros de
componente com o mesmo nome (não diferencia maiúsculas de minúsculas).

@page "/product/{id}"

<h1>Product @Id</h1>

@code {
[Parameter]
public string Id { get; set; }
}

Você também pode especificar restrições no valor do parâmetro de rota. Por exemplo, para restringir a ID do
produto a int :
@page "/product/{id:int}"

<h1>Product @Id</h1>

@code {
[Parameter]
public int Id { get; set; }
}

Para obter uma lista completa das restrições de rota com suporte pelo Blazor , consulte restrições de rota.

Componente do roteador
O roteamento no Blazor é tratado pelo Router componente. O Router componente é normalmente usado no
componente raiz do aplicativo (app. Razor).

<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

O Router componente descobre os componentes roteáveis no especificado AppAssembly e na opção


especificada AdditionalAssemblies . Quando o navegador navega, o Router intercepta a navegação e renderiza
o conteúdo de seu Found parâmetro com o extraído RouteData se uma rota corresponde ao endereço, caso
contrário, o Router renderiza seu NotFound parâmetro.
O RouteView componente lida com a renderização do componente correspondente especificado pelo RouteData
com seu layout, se ele tiver um. Se o componente correspondente não tiver um layout, a opção opcionalmente
especificada DefaultLayout será usada.
O LayoutView componente renderiza seu conteúdo filho dentro do layout especificado. Veremos os layouts mais
detalhadamente mais adiante neste capítulo.

Navegação
No ASP.NET Web Forms, você dispara a navegação para uma página diferente retornando uma resposta de
redirecionamento para o navegador. Por exemplo:

protected void NavigateButton_Click(object sender, EventArgs e)


{
Response.Redirect("Counter");
}

O retorno de uma resposta de redirecionamento geralmente não é possível no Blazor . BlazorNão usa um
modelo de solicitação-resposta. No entanto, é possível disparar navegações do navegador diretamente, como
você pode com o JavaScript.
Blazorfornece um NavigationManager serviço que pode ser usado para:
Obter o endereço do navegador atual
Obter o endereço base
Disparar navegações
Seja notificado quando o endereço for alterado
Para navegar para um endereço diferente, use o NavigateTo método:

@page "/"
@inject NavigationManager NavigationManager

<button @onclick="Navigate">Navigate</button>

@code {
void Navigate() {
NavigationManager.NavigateTo("counter");
}
}

Para obter uma descrição de todos os NavigationManager Membros, consulte URI e auxiliares de estado de
navegação.

URLs base
Se seu Blazor aplicativo for implantado em um caminho base, você precisará especificar a URL base nos
metadados da página usando a <base> marca para roteamento para a propriedade de trabalho. Se a página host
do aplicativo for renderizada pelo servidor usando o Razor, você poderá usar a ~/ sintaxe para especificar o
endereço base do aplicativo. Se a página host for HTML estático, você precisará especificar a URL base
explicitamente.

<base href="~/" />

Layout de página
O layout de página no ASP.NET Web Forms é manipulado por páginas mestras. As páginas mestras definem um
modelo com um ou mais espaços reservados de conteúdo que podem ser fornecidos por páginas individuais. As
páginas mestras são definidas em arquivos . Master e começam com a <%@ Master %> diretiva. O conteúdo dos
arquivos . Master é codificado como você faria com uma página . aspx , mas com a adição de
<asp:ContentPlaceHolder> controles para marcar onde as páginas podem fornecer conteúdo.

Site.master
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs"
Inherits="WebApplication1.SiteMaster" %>

<!DOCTYPE html>
<html lang="en">
<head runat="server">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><%: Page.Title %> - My ASP.NET Application</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
</head>
<body>
<form runat="server">
<div class="container body-content">
<asp:ContentPlaceHolder ID="MainContent" runat="server">
</asp:ContentPlaceHolder>
<hr />
<footer>
<p>&copy; <%: DateTime.Now.Year %> - My ASP.NET Application</p>
</footer>
</div>
</form>
</body>
</html>

No Blazor , você lida com o layout da página usando componentes de layout. Os componentes de layout herdam
de LayoutComponentBase , que define uma única Body Propriedade do tipo RenderFragment , que pode ser usada
para renderizar o conteúdo da página.
MainLayout. Razor

@inherits LayoutComponentBase
<h1>Main layout</h1>
<div>
@Body
</div>

Quando a página com um layout é renderizada, a página é renderizada dentro do conteúdo do layout
especificado no local em que o layout renderiza sua Body propriedade.
Para aplicar um layout a uma página, use a @layout diretiva:

@layout MainLayout

Você pode especificar o layout de todos os componentes em uma pasta e subpastas usando um arquivo
_Imports. Razor . Você também pode especificar um layout padrão para todas as suas páginas usando o
componente do roteador.
As páginas mestras podem definir vários espaços reservados de conteúdo, mas os layouts Blazor têm apenas
uma única Body propriedade. Essa limitação dos Blazor componentes de layout, felizmente, será abordada em
uma versão futura.
As páginas mestras no ASP.NET Web Forms podem ser aninhadas. Ou seja, uma página mestra também pode
usar uma página mestra. Os componentes de layout no Blazor também podem estar aninhados. Você pode
aplicar um componente de layout a um componente de layout. O conteúdo do layout interno será renderizado
dentro do layout externo.
ChildLayout. Razor
@layout MainLayout
<h2>Child layout</h2>
<div>
@Body
</div>

Index. Razor

@page "/"
@layout ChildLayout
<p>I'm in a nested layout!</p>

A saída renderizada para a página seria:

<h1>Main layout</h1>
<div>
<h2>Child layout</h2>
<div>
<p>I'm in a nested layout!</p>
</div>
</div>

Os layouts no Blazor não definem normalmente os elementos HTML raiz de uma página ( <html> ,, <body>
<head> e assim por diante). Os elementos HTML raiz são definidos na Blazor página host de um aplicativo, que é
usada para renderizar o conteúdo HTML inicial para o aplicativo (consulte Bootstrap Blazor ). A página host pode
renderizar vários componentes raiz para o aplicativo com marcação ao redor.
Os componentes no Blazor , incluindo páginas, não podem renderizar <script> marcas. Essa restrição de
renderização existe porque as <script> marcas são carregadas uma vez e não podem ser alteradas. Pode
ocorrer um comportamento inesperado se você tentar renderizar as marcas dinamicamente usando sintaxe
Razor. Em vez disso, todas as <script> marcas devem ser adicionadas à página host do aplicativo.

A N TE R IO R AVA N Ç A R
Gerenciamento de estado
24/07/2020 • 2 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Esse conteúdo será disponibilizado em breve.

A N TE R IO R AVA N Ç A R
Formulários e validação
24/07/2020 • 5 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

O ASP.NET Web Forms Framework inclui um conjunto de controles de servidor de validação que lidam com a
validação da entrada do usuário inserida em um formulário ( RequiredFieldValidator ,, CompareValidator
RangeValidator e assim por diante). O ASP.NET Web Forms Framework também dá suporte à associação de
modelo e à validação do modelo com base em anotações de dados ( [Required] ,, [StringLength] [Range] e
assim por diante). A lógica de validação pode ser imposta tanto no servidor quanto no cliente usando a validação
não invasiva baseada em JavaScript. O ValidationSummary controle de servidor é usado para exibir um resumo
dos erros de validação para o usuário.
Blazordá suporte ao compartilhamento de lógica de validação entre o cliente e o servidor. O ASP.NET fornece
implementações de JavaScript predefinidas de muitas validações de servidor comuns. Em muitos casos, o
desenvolvedor ainda precisa escrever JavaScript para implementar totalmente a lógica de validação específica do
aplicativo. Os mesmos tipos de modelo, anotações de dados e lógica de validação podem ser usados no servidor e
no cliente.
Blazorfornece um conjunto de componentes de entrada. Os componentes de entrada lidam com os dados do
campo de associação a um modelo e validam a entrada do usuário quando o formulário é enviado.

C O M P O N EN T E DE EN T RA DA EL EM EN TO H T M L REN DERIZ A DO

InputCheckbox <input type="checkbox">

InputDate <input type="date">

InputNumber <input type="number">

InputSelect <select>

InputText <input>

InputTextArea <textarea>

O EditForm componente encapsula esses componentes de entrada e orquestra o processo de validação por meio
de um EditContext . Ao criar um EditForm , especifique a instância de modelo a ser associada usando o Model
parâmetro. Normalmente, a validação é feita usando as anotações de dados e é extensível. Para habilitar a
validação baseada em anotação de dados, adicione o DataAnnotationsValidator componente como um filho do
EditForm . O EditForm componente fornece um evento conveniente para lidar com OnValidSubmit envios válidos
() e inválidos ( OnInvalidSubmit ). Há também um evento mais genérico OnSubmit que permite disparar e lidar
com a validação por conta própria.
Para exibir um resumo de erro de validação, use o ValidationSummary componente. Para exibir mensagens de
validação para um campo de entrada específico, use o ValidationMessage componente, especificando uma
expressão lambda para o For parâmetro que aponta para o membro de modelo apropriado.
O tipo de modelo a seguir define várias regras de validação usando anotações de dados:

using System;
using System.ComponentModel.DataAnnotations;

public class Starship


{
[Required]
[StringLength(16,
ErrorMessage = "Identifier too long (16 character limit).")]
public string Identifier { get; set; }

public string Description { get; set; }

[Required]
public string Classification { get; set; }

[Range(1, 100000,
ErrorMessage = "Accommodation invalid (1-100000).")]
public int MaximumAccommodation { get; set; }

[Required]
[Range(typeof(bool), "true", "true",
ErrorMessage = "This form disallows unapproved ships.")]
public bool IsValidatedDesign { get; set; }

[Required]
public DateTime ProductionDate { get; set; }
}

O componente a seguir demonstra como criar um formulário Blazor com base no Starship tipo de modelo:
<h1>New Ship Entry Form</h1>

<EditForm Model="@starship" OnValidSubmit="@HandleValidSubmit">


<DataAnnotationsValidator />
<ValidationSummary />

<p>
<label for="identifier">Identifier: </label>
<InputText id="identifier" @bind-Value="starship.Identifier" />
<ValidationMessage For="() => starship.Identifier" />
</p>
<p>
<label for="description">Description (optional): </label>
<InputTextArea id="description" @bind-Value="starship.Description" />
</p>
<p>
<label for="classification">Primary Classification: </label>
<InputSelect id="classification" @bind-Value="starship.Classification">
<option value="">Select classification ...</option>
<option value="Exploration">Exploration</option>
<option value="Diplomacy">Diplomacy</option>
<option value="Defense">Defense</option>
</InputSelect>
<ValidationMessage For="() => starship.Classification" />
</p>
<p>
<label for="accommodation">Maximum Accommodation: </label>
<InputNumber id="accommodation" @bind-Value="starship.MaximumAccommodation" />
<ValidationMessage For="() => starship.MaximumAccommodation" />
</p>
<p>
<label for="valid">Engineering Approval: </label>
<InputCheckbox id="valid" @bind-Value="starship.IsValidatedDesign" />
<ValidationMessage For="() => starship.IsValidatedDesign" />
</p>
<p>
<label for="productionDate">Production Date: </label>
<InputDate id="productionDate" @bind-Value="starship.ProductionDate" />
<ValidationMessage For="() => starship.ProductionDate" />
</p>

<button type="submit">Submit</button>
</EditForm>

@code {
private Starship starship = new Starship();

private void HandleValidSubmit()


{
// Save the data
}
}

Após o envio do formulário, os dados associados ao modelo não foram salvos em nenhum armazenamento de
dados, como um banco de dado. Em um Blazor WebAssembly aplicativo, os dados devem ser enviados para o
servidor. Por exemplo, usando uma solicitação HTTP POST. Em um Blazor aplicativo de servidor, os dados já estão
no servidor, mas devem persistir. O tratamento de acesso Blazor a dados em aplicativos é o assunto da seção
lidando com dados .

Recursos adicionais
Para obter mais informações sobre formulários e validação em Blazor aplicativos, consulte a Blazor documentação.
A N TE R IO R AVA N Ç A R
Trabalhar com dados
24/07/2020 • 12 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Acesso a dados é o backbone de um aplicativo ASP.NET Web Forms. Se você estiver criando formulários para a
Web, o que acontecerá com esses dados? Com Web Forms, havia várias técnicas de acesso a dados que podem
ser usadas para interagir com um banco de dados:
Data Sources
ADO.NET
Entity Framework
Fontes de dados eram controles que você pode fazer em uma Web Forms página e configurar como outros
controles. O Visual Studio forneceu um conjunto amigável de caixas de diálogo para configurar e associar os
controles às suas páginas de Web Forms. Os desenvolvedores que apreciam uma abordagem de "código baixo"
ou "sem código" preferem essa técnica quando Web Forms foi lançado pela primeira vez.

ADO.NET é a abordagem de nível baixo para interagir com um banco de dados. Seus aplicativos podem criar uma
conexão com o banco de dados com comandos, conjuntos de registros e conjuntos de dados para interação. Os
resultados podem então ser associados a campos na tela sem muito código. A desvantagem dessa abordagem
era que cada conjunto de objetos ADO.NET ( Connection , Command e Recordset ) foi associado a bibliotecas
fornecidas por um fornecedor de banco de dados. O uso desses componentes tornou o código rígido e difícil de
migrar para um banco de dados diferente.

Entity Framework
Entity Framework (EF) é a estrutura de mapeamento relacional de objeto de software livre mantida pelo .NET
Foundation. Lançado inicialmente com .NET Framework, o EF permite gerar código para as conexões de banco de
dados, esquemas de armazenamento e interações. Com essa abstração, você pode se concentrar nas regras de
negócios do seu aplicativo e permitir que o banco de dados seja gerenciado por um administrador de banco de
dados confiável. No .NET Core, você pode usar uma versão atualizada do EF chamada EF Core. EF Core ajuda a
gerar e manter as interações entre seu código e o banco de dados com uma série de comandos que estão
disponíveis para você usando a dotnet ef ferramenta de linha de comando. Vamos dar uma olhada em alguns
exemplos para ajudá-lo a trabalhar com um banco de dados.
Code First EF
Uma maneira rápida de começar a criar suas interações de banco de dados é começar com os objetos de classe
com os quais você deseja trabalhar. O EF fornece uma ferramenta para ajudar a gerar o código de banco de
dados apropriado para suas classes. Essa abordagem é chamada de desenvolvimento "Code First". Considere a
seguinte Product classe para um aplicativo de vitrine de exemplo que desejamos armazenar em um banco de
dados relacional como Microsoft SQL Server.

public class Product


{
public int Id { get; set; }

[Required]
public string Name { get; set; }

[MaxLength(4000)]
public string Description { get; set; }

[Range(0, 99999,99)]
[DataType(DataType.Currency)]
public decimal Price { get; set; }
}

O produto tem uma chave primária e três campos adicionais que seriam criados em nosso banco de dados:
O EF identificará a Id propriedade como uma chave primária por convenção.
Name será armazenado em uma coluna configurada para armazenamento de texto. O [Required] atributo
decoração dessa propriedade irá adicionar uma not null restrição para ajudar a impor esse comportamento
declarado da propriedade.
Description será armazenado em uma coluna configurada para armazenamento de texto e terá um
comprimento máximo configurado de 4000 caracteres, conforme determinado pelo [MaxLength] atributo. O
esquema de banco de dados será configurado com uma coluna chamada MaxLength usando o tipo de dados
varchar(4000) .
A Price propriedade será armazenada como moeda. O [Range] atributo irá gerar restrições apropriadas
para impedir o armazenamento de dados fora dos valores mínimo e máximo declarados.
Precisamos adicionar essa Product classe a uma classe de contexto de banco de dados que define as operações
de conexão e conversão com nosso banco de dados.

public class MyDbContext : DbContext


{
public DbSet<Product> Products { get; set; }
}

A MyDbContext classe fornece uma propriedade que define o acesso e a tradução da Product classe. Seu
aplicativo configura essa classe para interação com o banco de dados usando as seguintes entradas no Startup
método da classe ConfigureServices :

services.AddDbContext<MyDbContext>(options =>
options.UseSqlServer("MY DATABASE CONNECTION STRING"));

O código anterior se conectará a um banco de dados SQL Server com a cadeia de conexão especificada. Você
pode colocar a cadeia de conexão em seu appsettings.jsem arquivo, variáveis de ambiente ou outros locais de
armazenamento de configuração e substituir essa cadeia de caracteres inserida adequadamente.
Em seguida, você pode gerar a tabela de banco de dados apropriada para essa classe usando os seguintes
comandos:

dotnet ef migrations add 'Create Product table'


dotnet ef database update

O primeiro comando define as alterações que você está fazendo no esquema de banco de dados como uma nova
migração do EF chamada Create Product table . Uma migração define como aplicar e remover as novas
alterações no banco de dados.
Depois de aplicado, você tem uma Product tabela simples em seu banco de dados e algumas novas classes
adicionadas ao projeto que ajudam a gerenciar o esquema de banco de dados. Você pode encontrar essas classes
geradas, por padrão, em uma nova pasta chamada migrações. Ao fazer alterações na Product classe ou adicionar
mais classes relacionadas que você gostaria de interagir com o banco de dados, você precisa executar os
comandos de linha de comando novamente com um novo nome da migração. Esse comando gerará outro
conjunto de classes de migração para atualizar o esquema de banco de dados.
Database First EF
Para bancos de dados existentes, você pode gerar as classes para EF Core usando as ferramentas de linha de
comando do .NET. Para Scaffold as classes, use uma variação do seguinte comando:

dotnet ef dbcontext scaffold "CONNECTION STRING" Microsoft.EntityFrameworkCore.SqlServer -c MyDbContext -t


Product -t Customer

O comando anterior se conecta ao banco de dados usando a cadeia de conexão especificada e o


Microsoft.EntityFrameworkCore.SqlServer provedor. Uma vez conectado, uma classe de contexto de banco de
dados chamada MyDbContext é criada. Além disso, as classes de suporte são criadas para as Product Customer
tabelas e que foram especificadas com as -t opções. Há muitas opções de configuração para esse comando
gerar a hierarquia de classe apropriada para seu banco de dados. Para obter uma referência completa, consulte a
documentação do comando.
Mais informações sobre EF Core podem ser encontradas no site do Microsoft docs.

Interagir com os serviços Web


Quando o ASP.NET foi lançado pela primeira vez, os serviços SOAP eram a maneira preferida de servidores Web
e clientes de trocar dados. Muito mudou desde esse tempo, e as interações preferenciais com serviços mudaram
para direcionar interações de cliente HTTP. Com ASP.NET Core e Blazor , você pode registrar a configuração de
seu HttpClient no Startup método da classe ConfigureServices . Use essa configuração quando precisar
interagir com o ponto de extremidade HTTP. Considere o seguinte código de configuração:

services.AddHttpClient("github", client =>


{
client.BaseAddress = new Uri("http://api.github.com/");
// Github API versioning
client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
client.DefaultRequestHeaders.Add("User-Agent", "BlazorWebForms-Sample");
});

Sempre que você precisar acessar dados do GitHub, crie um cliente com um nome de github . O cliente é
configurado com o endereço base e os cabeçalhos de solicitação são definidos adequadamente. Insira o
IHttpClientFactory em seus Blazor componentes com a @inject diretiva ou um [Inject] atributo em uma
propriedade. Crie seu cliente nomeado e interaja com os serviços usando a seguinte sintaxe:
@inject IHttpClientFactory factory

...

@code {
protected override async Task OnInitializedAsync()
{
var client = factory.CreateClient("github");
var response = await client.GetAsync("repos/dotnet/docs/issues");
response.EnsureStatusCode();
var content = async response.Content.ReadAsStringAsync();
}
}

Esse método retorna a cadeia de caracteres que descreve a coleção de problemas no repositório do GitHub
dotnet/docs . Ele retorna o conteúdo no formato JSON e é desserializado em objetos de problema do GitHub
apropriados. Há várias maneiras pelas quais você pode configurar o HttpClientFactory para entregar
HttpClient objetos pré-configurados. Tente configurar várias HttpClient instâncias com nomes e pontos de
extremidade diferentes para os vários serviços Web com os quais você trabalha. Essa abordagem fará com que
as interações com esses serviços sejam mais fáceis de trabalhar em cada página. Para obter mais detalhes, leia a
documentação do IHttpClientFactory.

A N TE R IO R AVA N Ç A R
Módulos, manipuladores e middleware
24/07/2020 • 5 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Um aplicativo ASP.NET Core é criado com base em uma série de middleware. O middleware é manipuladores que
são organizados em um pipeline para lidar com solicitações e respostas. Em um aplicativo Web Forms,
manipuladores e módulos HTTP resolvem problemas semelhantes. Em ASP.NET Core, módulos, manipuladores,
global.asax.cse o ciclo de vida do aplicativo são substituídos por middleware. Neste capítulo, você aprenderá o que
é o middleware no contexto de um Blazor aplicativo.

Visão Geral
O pipeline de solicitação do ASP.NET Core consiste em uma sequência de delegados de solicitação, chamados um
após o outro. O diagrama a seguir demonstra o conceito. O thread de execução segue as setas pretas.

O diagrama anterior não tem um conceito de eventos de ciclo de vida. Esse conceito é fundamental para como as
solicitações de Web Forms ASP.NET são tratadas. Esse sistema torna mais fácil motivo de qual processo está
ocorrendo e permite que o middleware seja inserido em qualquer ponto. O middleware é executado na ordem em
que é adicionado ao pipeline de solicitação. Eles também são adicionados no código em vez de arquivos de
configuração, geralmente em Startup.cs.

Katana
Os leitores familiarizados com o Katana se sentirão confortáveis em ASP.NET Core. Na verdade, Katana é uma
estrutura da qual ASP.NET Core deriva. Ele apresentou middleware semelhante e padrões de pipeline para ASP.NET
4. x. O middleware projetado para Katana pode ser adaptado para funcionar com o pipeline de ASP.NET Core.
Middleware comum
O ASP.NET 4. x inclui muitos módulos. De maneira semelhante, ASP.NET Core também tem muitos componentes
de middleware disponíveis. Os módulos do IIS podem ser usados em alguns casos com ASP.NET Core. Em outros
casos, o middleware nativo ASP.NET Core pode estar disponível.
A tabela a seguir lista os componentes e middleware de substituição no ASP.NET Core.

M Ó DULO M Ó DULO A SP. N ET 4. X O P Ç Ã O A SP. N ET C O RE

Erros de HTTP CustomErrorModule Middleware de páginas de código de


status

Documento padrão DefaultDocumentModule Middleware de arquivos padrão

Pesquisa no diretório DirectoryListingModule Middleware de navegação no diretório

Compactação dinâmica DynamicCompressionModule Middleware de compactação de


resposta

Rastreamento de solicitações com falha FailedRequestsTracingModule Log de ASP.NET Core

Cache de arquivos FileCacheModule Middleware de cache de resposta

Cache HTTP HttpCacheModule Middleware de cache de resposta

Log de FTP HttpLoggingModule Log de ASP.NET Core

Redirecionamento HTTP HttpRedirectionModule Middleware de regravação de URL

Filtros ISAPI IsapiFilterModule Middleware

ISAPI IsapiModule Middleware

Filtragem de solicitações RequestFilteringModule Irule usando de middleware de


regravação de URL

Regravação de URL† RewriteModule Middleware de regravação de URL

Compactação estática StaticCompressionModule Middleware de compactação de


resposta

Conteúdo estático StaticFileModule Middleware de arquivos estáticos

Autorização de URL UrlAuthorizationModule Identidade do ASP.NET Core

Essa lista não é exaustiva, mas deve dar uma ideia de qual mapeamento existe entre as duas estruturas. Para obter
uma lista mais detalhada, consulte módulos do IIS com ASP.NET Core.

Middleware personalizado
O middleware interno pode não lidar com todos os cenários necessários para um aplicativo. Nesses casos, faz
sentido criar seu próprio middleware. Há várias maneiras de definir o middleware, com o mais simples de ser um
simples delegado. Considere o seguinte middleware, que aceita uma solicitação de cultura de uma cadeia de
caracteres de consulta:

public class Startup


{
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) =>
{
var cultureQuery = context.Request.Query["culture"];

if (!string.IsNullOrWhiteSpace(cultureQuery))
{
var culture = new CultureInfo(cultureQuery);

CultureInfo.CurrentCulture = culture;
CultureInfo.CurrentUICulture = culture;
}

// Call the next delegate/middleware in the pipeline


await next();
});

app.Run(async (context) =>


await context.Response.WriteAsync(
$"Hello {CultureInfo.CurrentCulture.DisplayName}"));
}
}

O middleware também pode ser definido como uma classe implementando a IMiddleware interface ou seguindo
a Convenção de middleware. Para obter mais informações, consulte Write custom ASP.NET Core middleware.

A N TE R IO R AVA N Ç A R
Configuração do aplicativo
24/07/2020 • 12 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

A principal maneira de carregar a configuração de aplicativo no Web Forms é com entradas no arquivo
web.config — no servidor ou em um arquivo de configuração relacionado referenciado por web.config. Você pode
usar o ConfigurationManager objeto estático para interagir com as configurações do aplicativo, cadeias de conexão
do repositório de dados e outros provedores de configuração estendidos que são adicionados ao aplicativo. É
comum ver interações com a configuração do aplicativo, como visto no código a seguir:

var configurationValue = ConfigurationManager.AppSettings["ConfigurationSettingName"];


var connectionString = ConfigurationManager.ConnectionStrings["MyDatabaseConnectionName"].ConnectionString;

Com ASP.NET Core e servidor Blazor , o arquivo de web.config pode estar presente se seu aplicativo estiver
hospedado em um servidor IIS do Windows. No entanto, não há nenhuma ConfigurationManager interação com
essa configuração, e você pode receber mais configurações de aplicativo estruturado de outras fontes. Vamos dar
uma olhada em como a configuração é coletada e como você ainda pode acessar as informações de configuração
de um arquivo web.config .

Fontes de configuração
ASP.NET Core reconhece que há muitas fontes de configuração que você pode querer usar para seu aplicativo. A
estrutura tenta oferecer o melhor desses recursos por padrão. A configuração é lida e agregada dessas várias
fontes por ASP.NET Core. Os valores carregados posteriormente para a mesma chave de configuração têm
precedência sobre os valores anteriores.
A ASP.NET Core foi projetada para ser compatível com a nuvem e para facilitar a configuração de aplicativos para
operadores e desenvolvedores. ASP.NET Core tem reconhecimento de ambiente e sabe se ele está em execução no
Production seu Development ambiente ou. O indicador de ambiente é definido na ASPNETCORE_ENVIRONMENT
variável de ambiente do sistema. Se nenhum valor for configurado, o aplicativo usa como padrão a execução no
Production ambiente.

Seu aplicativo pode disparar e adicionar a configuração de várias fontes com base no nome do ambiente. Por
padrão, a configuração é carregada dos seguintes recursos na ordem listada:
1. appsettings.jsno arquivo, se presente
2. appSettings. Arquivo {ENVIRONMENT_NAME}. JSON , se presente
3. Arquivo de segredos do usuário em disco, se presente
4. Variáveis de ambiente
5. Argumentos de linha de comando

appsettings.jsno formato e acesso


O appsettings.jsno arquivo pode ser hierárquico com valores estruturados como o JSON a seguir:

{
"section0": {
"key0": "value",
"key1": "value"
},
"section1": {
"key0": "value",
"key1": "value"
}
}

Quando apresentado com o JSON anterior, o sistema de configuração mescla valores filho e faz referência a seus
caminhos hierárquicos totalmente qualificados. Um caractere de dois-pontos ( : ) separa cada propriedade na
hierarquia. Por exemplo, a chave de configuração section1:key0 acessa o section1 valor do literal do objeto
key0 .

Segredos do usuário
Os segredos do usuário são:
Valores de configuração que são armazenados em um arquivo JSON na estação de trabalho do desenvolvedor,
fora da pasta de desenvolvimento do aplicativo.
Carregado somente quando executado no Development ambiente.
Associado a um aplicativo específico.
Gerenciado com o comando do CLI do .NET Core user-secrets .
Configure seu aplicativo para o armazenamento de segredos executando o user-secrets comando:

dotnet user-secrets init

O comando anterior adiciona um UserSecretsId elemento ao arquivo de projeto. O elemento contém um GUID,
que é usado para associar segredos ao aplicativo. Em seguida, você pode definir um segredo com o set
comando. Por exemplo:

dotnet user-secrets set "Parent:ApiKey" "12345"

O comando anterior disponibiliza a Parent:ApiKey chave de configuração na estação de trabalho de um


desenvolvedor com o valor 12345 .
Para obter mais informações sobre como criar, armazenar e gerenciar segredos do usuário, consulte o
armazenamento seguro de segredos do aplicativo em desenvolvimento no ASP.NET Core documento.

Variáveis de ambiente
O próximo conjunto de valores carregados em sua configuração de aplicativo são as variáveis de ambiente do
sistema. Todas as configurações de variável de ambiente do seu sistema agora estão acessíveis para você por
meio da API de configuração. Os valores hierárquicos são achatados e separados por caracteres de dois-pontos
quando lidos dentro de seu aplicativo. No entanto, alguns sistemas operacionais não permitem os nomes de
variável de ambiente de caractere de dois pontos. ASP.NET Core resolve essa limitação convertendo valores que
têm sublinhados duplos ( __ ) em dois pontos quando eles são acessados. O Parent:ApiKey valor da seção
segredos do usuário acima pode ser substituído pela variável de ambiente Parent__ApiKey .
Argumentos de linha de comando
A configuração também pode ser fornecida como argumentos de linha de comando quando seu aplicativo é
iniciado. Use a notação de traço duplo ( -- ) ou de barra ( / ) para indicar o nome do valor de configuração a
ser definido e o valor a ser configurado. A sintaxe é semelhante aos seguintes comandos:

dotnet run CommandLineKey1=value1 --CommandLineKey2=value2 /CommandLineKey3=value3


dotnet run --CommandLineKey1 value1 /CommandLineKey2 value2
dotnet run Parent:ApiKey=67890

O retorno de web.config
Se você tiver implantado seu aplicativo no Windows no IIS, o arquivo de web.config ainda configurará o IIS para
gerenciar seu aplicativo. Por padrão, o IIS adiciona uma referência ao módulo de ASP.NET Core (ANCM). ANCM é
um módulo do IIS nativo que hospeda seu aplicativo no lugar do servidor Web Kestrel. Esta seção web.config é
semelhante à marcação XML a seguir:

<?xml version="1.0" encoding="utf-8"?>


<configuration>
<location path="." inheritInChildApplications="false">
<system.webServer>
<handlers>
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
</handlers>
<aspNetCore processPath=".\MyApp.exe"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess" />
</system.webServer>
</location>
</configuration>

A configuração específica do aplicativo pode ser definida aninhando-se um environmentVariables elemento no


aspNetCore elemento. Os valores definidos nesta seção são apresentados ao aplicativo ASP.NET Core como
variáveis de ambiente. As variáveis de ambiente são carregadas adequadamente durante o segmento de
inicialização do aplicativo.

<aspNetCore processPath="dotnet"
arguments=".\MyApp.dll"
stdoutLogEnabled="false"
stdoutLogFile=".\logs\stdout"
hostingModel="inprocess">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
<environmentVariable name="Parent:ApiKey" value="67890" />
</environmentVariables>
</aspNetCore>

Ler a configuração no aplicativo


ASP.NET Core fornece a configuração de aplicativo por meio da IConfiguration interface. Essa interface de
configuração deve ser solicitada por seus Blazor componentes, Blazor páginas e qualquer outra classe gerenciada
ASP.NET Core que precise de acesso à configuração. A estrutura de ASP.NET Core preencherá automaticamente
essa interface com a configuração resolvida configurada anteriormente. Em uma Blazor página ou marcação
Razor de um componente, você pode injetar o IConfiguration objeto com uma @inject diretiva na parte
superior do arquivo . Razor como este:
@inject IConfiguration Configuration

Essa instrução anterior torna o IConfiguration objeto disponível como a Configuration variável em todo o
restante do modelo Razor.
As definições de configuração individuais podem ser lidas especificando-se a hierarquia de definição de
configuração procurada como um parâmetro de indexador:

var mySetting = Configuration["section1:key0"];

Você pode buscar seções de configuração inteiras usando o GetSection método para recuperar uma coleção de
chaves em um local específico com uma sintaxe semelhante a para GetSection("section1") recuperar a
configuração de section1 do exemplo anterior.

Configuração com rigidez de tipos


Com Web Forms, era possível criar um tipo de configuração fortemente tipado herdado do ConfigurationSection
tipo e dos tipos associados. Um ConfigurationSection permitia que você configure algumas regras de negócio e o
processamento para esses valores de configuração.
No ASP.NET Core, você pode especificar uma hierarquia de classe que receberá os valores de configuração. Essas
classes:
Não é necessário herdar de uma classe pai.
Deve incluir public Propriedades que correspondam às propriedades e referências de tipo para a estrutura de
configuração que você deseja capturar.
Para o appsettings.jsanterior no exemplo, você pode definir as seguintes classes para capturar os valores:

public class MyConfig


{
public MyConfigSection section0 { get; set;}

public MyConfigSection section1 { get; set;}


}

public class MyConfigSection


{
public string key0 { get; set; }

public string key1 { get; set; }


}

Essa hierarquia de classe pode ser populada adicionando a seguinte linha ao Startup.ConfigureServices método:

services.Configure<MyConfig>(Configuration);

No restante do aplicativo, você pode adicionar um parâmetro de entrada a classes ou uma @inject diretiva em
modelos do Razor do tipo IOptions<MyConfig> para receber as definições de configuração com rigidez de tipos. A
IOptions<MyConfig>.Value Propriedade produzirá o MyConfig valor populado a partir das definições de
configuração.
@inject IOptions<MyConfig> options
@code {
var MyConfiguration = options.Value;
var theSetting = MyConfiguration.section1.key0;
}

Mais informações sobre o recurso de opções podem ser encontradas no padrão de opções no documento
ASP.NET Core .

A N TE R IO R AVA N Ç A R
Segurança: autenticação e autorização no ASP.NET
Web Forms eBlazor
24/07/2020 • 2 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Esse conteúdo será disponibilizado em breve.

A N TE R IO R AVA N Ç A R
Migrar do ASP.NET Web Forms paraBlazor
24/07/2020 • 30 minutes to read • Edit Online

IMPORTANT
EDIÇÃO DE PRÉ-VISUALIZAÇÃO
Este artigo fornece conteúdo inicial de um livro que está atualmente em construção. Se você tiver algum feedback, envie-o
em https://aka.ms/ebookfeedback.

Migrar uma base de código do ASP.NET Web Forms para Blazor é uma tarefa demorada que requer planejamento.
Este capítulo descreve o processo. Algo que pode facilitar a transição é garantir que o aplicativo obedeça a uma
arquitetura de N camadas , na qual o modelo de aplicativo (nesse caso, Web Forms) é separado da lógica de
negócios. Essa separação lógica de camadas torna claro o que precisa ser movido para o .NET Core e Blazor .
Para este exemplo, o aplicativo eShop disponível no GitHub é usado. eShop é um serviço de catálogo que fornece
recursos CRUD por meio de entrada e validação de formulário.
Por que um aplicativo de trabalho deve ser migrado para Blazor ? Muitas vezes, não há necessidade. O ASP.NET
Web Forms continuará a ter suporte por muitos anos. No entanto, muitos dos recursos que o Blazor fornece têm
suporte apenas em um aplicativo migrado. Esses recursos incluem:
Melhorias de desempenho na estrutura, como Span<T>
Capacidade de executar comoWebAssembly
Suporte de plataforma cruzada para Linux e macOS
Implantação de aplicativo-local ou implantação de estrutura compartilhada sem afetar outros aplicativos
Se esses ou outros novos recursos forem atraentes o suficiente, pode haver um valor na migração do aplicativo. A
migração pode ter formas diferentes; pode ser o aplicativo inteiro ou apenas determinados pontos de extremidade
que exigem as alterações. A decisão de migrar é, por fim, baseada nos problemas de negócios a serem resolvidos
pelo desenvolvedor.

Hospedagem do lado do servidor em comparação com o lado do


cliente
Conforme descrito no capítulo modelos de hospedagem , um Blazor aplicativo pode ser hospedado de duas
maneiras diferentes: lado do servidor e do cliente. O modelo do lado do servidor usa ASP.NET Core conexões de
sinalização para gerenciar as atualizações do DOM durante a execução de qualquer código real no servidor. O
modelo do lado do cliente é executado como WebAssembly em um navegador e não requer conexões de servidor.
Há várias diferenças que podem afetar o que é melhor para um aplicativo específico:
Em execução como WebAssembly ainda está em desenvolvimento e pode não dar suporte a todos os recursos
(como Threading) no momento atual
A comunicação informal entre o cliente e o servidor pode causar problemas de latência no modo do servidor
O acesso a bancos de dados e serviços internos ou protegidos requer um serviço separado com hospedagem
do lado do cliente
No momento da elaboração do artigo, o modelo do lado do servidor se assemelha mais à Web Forms. A maior
parte deste capítulo se concentra no modelo de hospedagem do lado do servidor, pois ele está pronto para
produção.
Criar um projeto
Essa etapa inicial de migração é criar um novo projeto. Esse tipo de projeto se baseia nos projetos de estilo do SDK
do .NET Core e simplifica grande parte do timbre que foi usado em formatos de projeto anteriores. Para obter mais
detalhes, consulte o capítulo sobre estrutura do projeto.
Depois que o projeto tiver sido criado, instale as bibliotecas que foram usadas no projeto anterior. Em projetos de
Web Forms mais antigos, você pode ter usado o arquivo de packages.config para listar os pacotes NuGet
necessários. No novo projeto no estilo SDK, packages.config foi substituído por <PackageReference> elementos no
arquivo de projeto. Um benefício para essa abordagem é que todas as dependências são instaladas de maneira
transitiva. Você só lista as dependências de nível superior que se preocupam.
Muitas das dependências que você está usando estão disponíveis para o .NET Core, incluindo Entity Framework 6 e
log4net. Se não houver nenhuma versão do .NET Core ou do .NET Standard disponível, a versão .NET Framework
poderá ser usada com frequência. Sua quilometragem pode variar. Qualquer API usada que não esteja disponível
no .NET Core causa um erro de tempo de execução. O Visual Studio o notifica sobre esses pacotes. Um ícone
amarelo aparece no nó referências do projeto no Gerenciador de soluções .
No Blazor projeto eshop baseado em, você pode ver os pacotes que estão instalados. Anteriormente, o arquivo de
packages.config listava cada pacote usado no projeto, resultando em um arquivo com quase 50 linhas de
comprimento. Um trecho de packages.config é:

<?xml version="1.0" encoding="utf-8"?>


<packages>
...
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.4.0" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.Web" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.9.1" targetFramework="net472" />
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.9.1"
targetFramework="net472" />
<package id="Microsoft.AspNet.FriendlyUrls" version="1.0.2" targetFramework="net472" />
<package id="Microsoft.AspNet.FriendlyUrls.Core" version="1.0.2" targetFramework="net472" />
<package id="Microsoft.AspNet.ScriptManager.MSAjax" version="5.0.0" targetFramework="net472" />
<package id="Microsoft.AspNet.ScriptManager.WebForms" version="5.0.0" targetFramework="net472" />
...
<package id="System.Memory" version="4.5.1" targetFramework="net472" />
<package id="System.Numerics.Vectors" version="4.4.0" targetFramework="net472" />
<package id="System.Runtime.CompilerServices.Unsafe" version="4.5.0" targetFramework="net472" />
<package id="System.Threading.Channels" version="4.5.0" targetFramework="net472" />
<package id="System.Threading.Tasks.Extensions" version="4.5.1" targetFramework="net472" />
<package id="WebGrease" version="1.6.0" targetFramework="net472" />
</packages>

O <packages> elemento inclui todas as dependências necessárias. É difícil identificar quais desses pacotes são
incluídos porque você precisa deles. Alguns <package> elementos são listados simplesmente para atender às
necessidades de dependências que você precisa.
O Blazor projeto lista as dependências que você precisa dentro de um <ItemGroup> elemento no arquivo de
projeto:

<ItemGroup>
<PackageReference Include="Autofac" Version="4.9.3" />
<PackageReference Include="EntityFramework" Version="6.3.0-preview9-19423-04" />
<PackageReference Include="log4net" Version="2.0.8" />
</ItemGroup>

Um pacote NuGet que simplifica a vida de Web Forms desenvolvedores é o pacote de compatibilidade do
Windows. Embora o .NET Core seja uma plataforma cruzada, alguns recursos estão disponíveis apenas no
Windows. Os recursos específicos do Windows são disponibilizados pela instalação do Compatibility Pack.
Exemplos de tais recursos incluem o registro, o WMI e os serviços de diretório. O pacote acrescenta cerca de
20.000 APIs e ativa muitos serviços com os quais você já deve estar familiarizado. O projeto eShop não requer o
Compatibility Pack; Mas se seus projetos usarem recursos específicos do Windows, o pacote facilitará os esforços
de migração.

Habilitar processo de inicialização


O processo de inicialização do Blazor foi alterado de Web Forms e segue uma configuração semelhante para
outros serviços de ASP.NET Core. Quando hospedados no lado do servidor, Blazor os componentes são executados
como parte de um aplicativo ASP.NET Core normal. Quando hospedado no navegador com WebAssembly , os
Blazor componentes usam um modelo de hospedagem semelhante. A diferença é que os componentes são
executados como um serviço separado de qualquer um dos processos de back-end. De qualquer forma, a
inicialização é semelhante.
O arquivo global.asax.cs é a página de inicialização padrão para projetos Web Forms. No projeto eShop, esse
arquivo configura o contêiner inversão de controle (IoC) e manipula os vários eventos de ciclo de vida do
aplicativo ou da solicitação. Alguns desses eventos são tratados com middleware (como Application_BeginRequest
). Outros eventos exigem a substituição de serviços específicos por meio de injeção de dependência (DI).
Por exemplo, o arquivo global.asax.cs para eshop contém o seguinte código:
public class Global : HttpApplication, IContainerProviderAccessor
{
private static readonly ILog _log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

static IContainerProvider _containerProvider;


IContainer container;

public IContainerProvider ContainerProvider


{
get { return _containerProvider; }
}

protected void Application_Start(object sender, EventArgs e)


{
// Code that runs on app startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureContainer();
ConfigDataBase();
}

/// <summary>
/// Track the machine name and the start time for the session inside the current session
/// </summary>
protected void Session_Start(Object sender, EventArgs e)
{
HttpContext.Current.Session["MachineName"] = Environment.MachineName;
HttpContext.Current.Session["SessionStartTime"] = DateTime.Now;
}

/// <summary>
/// https://autofaccn.readthedocs.io/en/latest/integration/webforms.html
/// </summary>
private void ConfigureContainer()
{
var builder = new ContainerBuilder();
var mockData = bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);
builder.RegisterModule(new ApplicationModule(mockData));
container = builder.Build();
_containerProvider = new ContainerProvider(container);
}

private void ConfigDataBase()


{
var mockData = bool.Parse(ConfigurationManager.AppSettings["UseMockData"]);

if (!mockData)
{
Database.SetInitializer<CatalogDBContext>(container.Resolve<CatalogDBInitializer>());
}
}

protected void Application_BeginRequest(object sender, EventArgs e)


{
//set the property to our new object
LogicalThreadContext.Properties["activityid"] = new ActivityIdHelper();

LogicalThreadContext.Properties["requestinfo"] = new WebRequestInfo();

_log.Debug("Application_BeginRequest");
}
}

O arquivo anterior torna-se a Startup classe no lado do servidor Blazor :


public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
}

public IConfiguration Configuration { get; }

public IWebHostEnvironment Env { get; }

// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?
LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages();
services.AddServerSideBlazor();

if (Configuration.GetValue<bool>("UseMockData"))
{
services.AddSingleton<ICatalogService, CatalogServiceMock>();
}
else
{
services.AddScoped<ICatalogService, CatalogService>();
services.AddScoped<IDatabaseInitializer<CatalogDBContext>, CatalogDBInitializer>();
services.AddSingleton<CatalogItemHiLoGenerator>();
services.AddScoped(_ => new
CatalogDBContext(Configuration.GetConnectionString("CatalogDBContext")));
}
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddLog4Net("log4Net.xml");

if (Env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}

// Middleware for Application_BeginRequest


app.Use((ctx, next) =>
{
LogicalThreadContext.Properties["activityid"] = new ActivityIdHelper(ctx);
LogicalThreadContext.Properties["requestinfo"] = new WebRequestInfo(ctx);
return next();
});

app.UseStaticFiles();

app.UseRouting();

app.UseEndpoints(endpoints =>
{
endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});

ConfigDataBase(app);
}
private void ConfigDataBase(IApplicationBuilder app)
{
using (var scope = app.ApplicationServices.CreateScope())
{
var initializer = scope.ServiceProvider.GetService<IDatabaseInitializer<CatalogDBContext>>();

if (initializer != null)
{
Database.SetInitializer(initializer);
}
}
}
}

Uma alteração significativa que você pode observar de Web Forms é a proeminência de DI. DI foi um princípio de
orientação no design de ASP.NET Core. Ele dá suporte à personalização de quase todos os aspectos da estrutura de
ASP.NET Core. Há até mesmo um provedor de serviços interno que pode ser usado em muitos cenários. Se for
necessária mais personalização, ela poderá ser suportada pelos vários projetos da Comunidade. Por exemplo, você
pode transportar seu investimento de biblioteca de DI de terceiros.
No aplicativo eShop original, há alguma configuração para o gerenciamento de sessão. Como o lado do servidor
Blazor usa ASP.NET Core signalr para comunicação, o estado da sessão não é suportado, pois as conexões podem
ocorrer independentemente de um contexto http. Um aplicativo que usa o estado de sessão requer a
reestruturação antes da execução como um Blazor aplicativo.
Para obter mais informações sobre a inicialização do aplicativo, consulte inicialização do aplicativo.

Migrar módulos e manipuladores HTTP para middleware


Os módulos e manipuladores HTTP são padrões comuns em Web Forms para controlar o pipeline de solicitação
HTTP. Classes que implementam IHttpModule ou IHttpHandler podem ser registradas e processar solicitações de
entrada. Web Forms configura módulos e manipuladores no arquivo web.config . O Web Forms também é muito
baseado na manipulação de eventos do ciclo de vida do aplicativo. O ASP.NET Core usa o middleware em vez disso.
O middleware é registrado no Configure método da Startup classe. A ordem de execução do middleware é
determinada pela ordem de registro.
Na seção habilitar processo de inicialização , um evento de ciclo de vida foi gerado por Web Forms como o
Application_BeginRequest método. Esse evento não está disponível no ASP.NET Core. Uma maneira de atingir esse
comportamento é implementar o middleware como visto no exemplo de arquivo Startup.cs . Esse middleware faz
a mesma lógica e, em seguida, transfere o controle para o próximo manipulador no pipeline de middleware.
Para obter mais informações sobre como migrar módulos e manipuladores, consulte migrar manipuladores e
módulos http para ASP.NET Core middleware.

Migrar arquivos estáticos


Para servir arquivos estáticos (por exemplo, HTML, CSS, imagens e JavaScript), os arquivos devem ser expostos
por middleware. Chamar o UseStaticFiles método permite o serviço de arquivos estáticos do caminho raiz da
Web. O diretório raiz padrão da Web é wwwroot, mas pode ser personalizado. Conforme incluído no Configure
método da Startup classe eshop:
public void Configure(IApplicationBuilder app)
{
...

app.UseStaticFiles();

...
}

O projeto eShop habilita o acesso básico a arquivos estáticos. Há muitas personalizações disponíveis para acesso a
arquivos estáticos. Para obter informações sobre como habilitar arquivos padrão ou um navegador de arquivos,
consulte arquivos estáticos em ASP.NET Core.

Migrar a configuração de agrupamento e minificação de tempo de


execução
O agrupamento e o minificação são técnicas de otimização de desempenho para reduzir o número e o tamanho
das solicitações de servidor para recuperar determinados tipos de arquivo. O JavaScript e o CSS geralmente
passam por alguma forma de agrupamento ou minificação antes de serem enviados ao cliente. No ASP.NET Web
Forms, essas otimizações são tratadas em tempo de execução. As convenções de otimização são definidas como
um arquivo App_Start/bundleconfig.cs . No ASP.NET Core, uma abordagem mais declarativa é adotada. Um
arquivo lista os arquivos a serem reduzidosdos, juntamente com configurações específicas de minificação.
Para obter mais informações sobre agrupamento e minificação, consulte ativos estáticos de pacote e reduzir em
ASP.NET Core.

Migrar páginas ASPX


Uma página em um aplicativo Web Forms é um arquivo com a extensão . aspx . Uma página de Web Forms
geralmente pode ser mapeada para um componente no Blazor . Um Blazor componente é criado em um arquivo
com a extensão . Razor . Para o projeto eShop, cinco páginas são convertidas em uma página Razor.
Por exemplo, a exibição de detalhes compreende três arquivos na Web Forms projeto: Details. aspx, Details.aspx.cse
Details.aspx.designer.cs. Ao converter para Blazor , o code-behind e a marcação são combinados em Details. Razor.
A compilação do Razor (equivalente ao que está nos arquivos . designer.cs ) é armazenada no diretório obj e não é,
por padrão, visível no Gerenciador de soluções . A página Web Forms consiste na seguinte marcação:

<%@ Page Title="Details" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"


CodeBehind="Details.aspx.cs" Inherits="eShopLegacyWebForms.Catalog.Details" %>

<asp:Content ID="Details" ContentPlaceHolderID="MainContent" runat="server">


<h2 class="esh-body-title">Details</h2>

<div class="container">
<div class="row">
<asp:Image runat="server" CssClass="col-md-6 esh-picture" ImageUrl='<%#"/Pics/" +
product.PictureFileName%>' />
<dl class="col-md-6 dl-horizontal">
<dt>Name
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.Name%>' />
</dd>

<dt>Description
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.Description%>' />
</dd>

<dt>Brand
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.CatalogBrand.Brand%>' />
</dd>

<dt>Type
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.CatalogType.Type%>' />
</dd>
<dt>Price
</dt>

<dd>
<asp:Label CssClass="esh-price" runat="server" Text='<%#product.Price%>' />
</dd>

<dt>Picture name
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.PictureFileName%>' />
</dd>

<dt>Stock
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.AvailableStock%>' />
</dd>

<dt>Restock
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.RestockThreshold%>' />
</dd>

<dt>Max stock
</dt>

<dd>
<asp:Label runat="server" Text='<%#product.MaxStockThreshold%>' />
</dd>

</dl>
</div>

<div class="form-actions no-color esh-link-list">


<a runat="server" href='<%# GetRouteUrl("EditProductRoute", new {id =product.Id}) %>' class="esh-
link-item">Edit
</a>
|
<a runat="server" href="~" class="esh-link-item">Back to list
</a>
</div>

</div>
</asp:Content>

O code-behind da marcação anterior inclui o seguinte código:


using eShopLegacyWebForms.Models;
using eShopLegacyWebForms.Services;
using log4net;
using System;
using System.Web.UI;

namespace eShopLegacyWebForms.Catalog
{
public partial class Details : System.Web.UI.Page
{
private static readonly ILog _log =
LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

protected CatalogItem product;

public ICatalogService CatalogService { get; set; }

protected void Page_Load(object sender, EventArgs e)


{
var productId = Convert.ToInt32(Page.RouteData.Values["id"]);
_log.Info($"Now loading... /Catalog/Details.aspx?id={productId}");
product = CatalogService.FindCatalogItem(productId);

this.DataBind();
}
}
}

Quando convertido em Blazor , a página Web Forms se traduz no seguinte código:

@page "/Catalog/Details/{id:int}"
@inject ICatalogService CatalogService
@inject ILogger<Details> Logger

<h2 class="esh-body-title">Details</h2>

<div class="container">
<div class="row">
<img class="col-md-6 esh-picture" src="@($"/Pics/{_item.PictureFileName}")">

<dl class="col-md-6 dl-horizontal">


<dt>
Name
</dt>

<dd>
@_item.Name
</dd>

<dt>
Description
</dt>

<dd>
@_item.Description
</dd>

<dt>
Brand
</dt>

<dd>
@_item.CatalogBrand.Brand
</dd>

<dt>
Type
</dt>

<dd>
@_item.CatalogType.Type
</dd>
<dt>
Price
</dt>

<dd>
@_item.Price
</dd>

<dt>
Picture name
</dt>

<dd>
@_item.PictureFileName
</dd>

<dt>
Stock
</dt>

<dd>
@_item.AvailableStock
</dd>

<dt>
Restock
</dt>

<dd>
@_item.RestockThreshold
</dd>

<dt>
Max stock
</dt>

<dd>
@_item.MaxStockThreshold
</dd>

</dl>
</div>

<div class="form-actions no-color esh-link-list">


<a href="@($"/Catalog/Edit/{_item.Id}")" class="esh-link-item">
Edit
</a>
|
<a href="/" class="esh-link-item">
Back to list
</a>
</div>

</div>

@code {
private CatalogItem _item;

[Parameter]
public int Id { get; set; }

protected override void OnInitialized()


{
{
Logger.LogInformation("Now loading... /Catalog/Details/{Id}", Id);

_item = CatalogService.FindCatalogItem(Id);
}
}

Observe que o código e a marcação estão no mesmo arquivo. Todos os serviços necessários são tornados
acessíveis com o @inject atributo. De acordo @page com a diretiva, essa página pode ser acessada na
Catalog/Details/{id} rota. O valor do espaço reservado da rota foi {id} restrito a um número inteiro. Conforme
descrito na seção de Roteamento , ao contrário de Web Forms, um componente Razor declara explicitamente sua
rota e quaisquer parâmetros que estejam incluídos. Muitos controles de Web Forms podem não ter as
contrapartes exatas no Blazor . Geralmente, há um trecho HTML equivalente que terá a mesma finalidade. Por
exemplo, o <asp:Label /> controle pode ser substituído por um <label> elemento HTML.
Validação de modelo emBlazor
Se seu código de Web Forms inclui validação, você pode transferir grande parte do que tem com pouca ou
nenhuma alteração. Um benefício para executar Blazor o no é que a mesma lógica de validação pode ser executada
sem a necessidade de JavaScript personalizado. As anotações de dados permitem uma validação fácil de modelo.
Por exemplo, a página Create. aspx tem um formulário de entrada de dados com validação. Um trecho de código
de exemplo ficaria assim:

<div class="form-group">
<label class="control-label col-md-2">Name</label>
<div class="col-md-3">
<asp:TextBox ID="Name" runat="server" CssClass="form-control"></asp:TextBox>
<asp:RequiredFieldValidator runat="server" ControlToValidate="Name" Display="Dynamic"
CssClass="field-validation-valid text-danger" ErrorMessage="The Name field is required." />
</div>
</div>

No Blazor , a marcação equivalente é fornecida em um arquivo Create. Razor :

<EditForm Model="_item" OnValidSubmit="@...">


<DataAnnotationsValidator />

<div class="form-group">
<label class="control-label col-md-2">Name</label>
<div class="col-md-3">
<InputText class="form-control" @bind-Value="_item.Name" />
<ValidationMessage For="(() => _item.Name)" />
</div>
</div>

...
</EditForm>

O EditForm contexto inclui suporte à validação e pode ser disposto em torno da entrada. As anotações de dados
são uma maneira comum de adicionar validação. Esse suporte à validação pode ser adicionado por meio do
DataAnnotationsValidator componente. Para obter mais informações sobre esse mecanismo, consulte ASP.NET
Core Blazor Forms and Validation.

Migrar controles de Web Forms internos


Esse conteúdo será disponibilizado em breve.

Migrar configuração
Em um projeto Web Forms, os dados de configuração são mais comumente armazenados no arquivo web.config .
Os dados de configuração são acessados com o ConfigurationManager . Normalmente, os serviços eram
necessários para analisar objetos. Com o .NET Framework 4.7.2, a capacidade de composição foi adicionada à
configuração via ConfigurationBuilders . Esses construtores permitiam que os desenvolvedores adicionassem
várias fontes de configuração que, em seguida, eram compostas em tempo de execução para recuperar os valores
necessários.
ASP.NET Core introduziu um sistema de configuração flexível que permite que você defina a fonte de configuração
ou as fontes usadas pelo seu aplicativo e sua implantação. A ConfigurationBuilder infraestrutura que você pode
estar usando em seu aplicativo Web Forms foi modelada após os conceitos usados no sistema de configuração de
ASP.NET Core.
O trecho a seguir demonstra como o projeto Web Forms eShop usa web.config para armazenar valores de
configuração:

<configuration>
<configSections>
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection,
EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"
/>
</configSections>
<connectionStrings>
<add name="CatalogDBContext" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial
Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated Security=True;
MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="UseMockData" value="true" />
<add key="UseCustomizationData" value="false" />
</appSettings>
</configuration>

É comum que segredos, como cadeias de conexão de banco de dados, sejam armazenados dentro do web.config.
Os segredos são inevitavelmente persistentes em locais não seguros, como o controle do código-fonte. Com o
Blazor no ASP.NET Core, a configuração baseada em XML anterior é substituída pelo JSON a seguir:

{
"ConnectionStrings": {
"CatalogDBContext": "Data Source=(localdb)\\MSSQLLocalDB; Initial
Catalog=Microsoft.eShopOnContainers.Services.CatalogDb; Integrated Security=True;
MultipleActiveResultSets=True;"
},
"UseMockData": true,
"UseCustomizationData": false
}

JSON é o formato de configuração padrão; no entanto, o ASP.NET Core dá suporte a muitos outros formatos,
incluindo XML. Também há vários formatos com suporte da Comunidade.
O Construtor na Blazor classe do projeto Startup aceita uma IConfiguration instância por meio de uma técnica
de di, conhecida como injeção de construtor:
public class Startup
{
public Startup(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
Env = env;
}

...
}

Por padrão, variáveis de ambiente, arquivos JSON (appsettings.jsem e appSettings. { Environment}. JSON) e as
opções de linha de comando são registradas como fontes de configuração válidas no objeto de configuração. As
fontes de configuração podem ser acessadas via Configuration[key] . Uma técnica mais avançada é associar os
dados de configuração a objetos usando o padrão de opções. Para obter mais informações sobre configuração e o
padrão de opções, consulte configuração no padrão de ASP.NET Core e opções em ASP.NET Core, respectivamente.

Migrar acesso a dados


O acesso a dados é um aspecto importante de qualquer aplicativo. O projeto eShop armazena as informações de
catálogo em um banco de dados e recupera os dados com Entity Framework (EF) 6. Como o EF 6 tem suporte no
.NET Core 3,0, o projeto pode continuar a usá-lo.
As seguintes alterações relacionadas ao EF foram necessárias para eShop:
Em .NET Framework, o DbContext objeto aceita uma cadeia de caracteres do formato Name =
ConnectionString e usa a cadeia de conexão de ConfigurationManager.AppSettings[ConnectionString] para se
conectar. No .NET Core, não há suporte para isso. A cadeia de conexão deve ser fornecida.
O banco de dados foi acessado de forma síncrona. Embora isso funcione, a escalabilidade pode ser afetada.
Essa lógica deve ser movida para um padrão assíncrono.
Embora não haja o mesmo suporte nativo para associação de conjunto de recursos, o Blazor fornece flexibilidade e
potência com seu suporte C# em uma página Razor. Por exemplo, você pode executar cálculos e exibir o resultado.
Para obter mais informações sobre padrões de dados no Blazor , consulte o capítulo de acesso a dados .

Alterações de arquitetura
Por fim, há algumas diferenças de arquitetura importantes a serem consideradas ao migrar para o Blazor . Muitas
dessas alterações são aplicáveis a qualquer coisa com base no .NET Core ou ASP.NET Core.
Como o Blazor é criado no .NET Core, há considerações sobre como garantir o suporte no .NET Core. Algumas das
principais alterações incluem a remoção dos seguintes recursos:
Vários AppDomains
Comunicação remota
CAS (segurança de acesso ao código)
Transparência de Segurança
Para obter mais informações sobre técnicas para identificar as alterações necessárias para dar suporte à execução
no .NET Core, consulte portar seu código do .NET Framework para o .NET Core.
ASP.NET Core é uma versão reimaginada do ASP.NET e tem algumas alterações que podem não parecer óbvias
inicialmente. As principais alterações são:
Nenhum contexto de sincronização, o que significa que não há HttpContext.Current , Thread.CurrentPrincipal
ou outros acessadores estáticos
Sem cópia de sombra
Nenhuma fila de solicitações
Muitas operações no ASP.NET Core são assíncronas, o que permite o descarregamento mais fácil de tarefas
vinculadas a e/s. É importante nunca Bloquear usando Task.Wait() Task.GetResult() o ou o, que pode esgotar
rapidamente os recursos do pool de threads.

Conclusão da migração
Neste ponto, você viu muitos exemplos do que é necessário para mover um projeto Web Forms para o Blazor .
Para obter um exemplo completo, consulte o projeto eShopOn Blazor .

A N TE R IO R

Potrebbero piacerti anche