VAGAS DE EMPREGO

balta.io balta.io
  • Cursos
  • Carreiras
  • Para sua Empresa
  • Livros
    • Background Services
    • Blazor com .NET 8
    • Segurança em APIs
    • Futuro do C# 12
    • Nullable Types
    • Clean Code
  • Blog

Seja Premium
balta.io

  • Cursos
  • Carreiras
  • Para sua Empresa
  • Agenda
  • Livros
    • Background Services
    • Blazor com .NET 8
    • Segurança em APIs
    • Futuro do C# 12
    • Nullable Types
    • Clean Code
  • Blog
  • Player
Seja Premium

Entre ou Cadastre-se

  • Home
  • Artigos
  • Blazor - Rotas e Navegação


👉 Temos uma versão mais atualizada deste artigo no nosso novo Blog

Blazor - Rotas e Navegação

📗 eBook COMPLETO: Blazor com .NET 8

  • 👉 Clique aqui para baixar seu eBook 👈

O Blazor trabalha de forma extremamente simples com rotas e navegação, e se você já aprendeu um pouco sobre isto no curso gratuito de Razor Pages, estará mais do que em casa aqui.

Isto por que dado um atributo @page em um arquivo .razor, o mesmo se torna automaticamente uma rota.

Inclusive, precisamos nos policiar para não termos rotas iguais, desta forma, recomendo que estruture bem as pastas e organize bem seu projeto.

⚠️ IMPORTANTE Você não precisa seguir a estrutura de exemplo dos projetos Blazor, você pode criar as suas, inclusive recomendo que utilize a separação por funcionalidades ou áreas ao invés de ter uma única pasta para páginas e componentes.

Rotas

Indo direto ao ponto, sempre que definimos um atributo @page temos uma rota, que deve ser no formato string e começar com “/”.

@page "/counter"
// https://localhost:xxxx/counter

Desta forma, se criarmos um arquivo chamado About.razor na pasta Components/Pages com o seguinte conteúdo:

@page "/about"

<h1>About this book</h1>

Teremos como resultado o seguinte conteúdo sendo exibido, sempre que navegarmos para URL https://localhost:xxxx/about.

Untitled

Da mesma forma, podemos alterar a URL para ter mais segmentos, e continuar com um resulta similar.

@page "/about/this-book"

<h1>About this book</h1>

Isto ocorre por que o uso de “/” e “-” na URL é plenamente permitido, então a renderização da página segue normalmente.

![Untitled](https://raw.githubusercontent.com/balta-io/blog/main/blazor-rotas-navegacao/images/Untitled 1.png)

Por fim, pouco importa onde sua página está, se houver o atributo @page no começo do seu arquivo, ele será adicionado as rotas.

![Untitled](https://raw.githubusercontent.com/balta-io/blog/main/blazor-rotas-navegacao/images/Untitled 2.png)

Desta forma, temos um arquivo Manage.razor em uma subpasta, dentro de outra subpasta, que contém o atributo @page como mostrado abaixo.

@page "/admin/account/manage"

<h1>Manage Your Account</h1>

E como resultado, temos a página sendo renderizada normalmente, visto que não faz diferença em qual pasta ela está alocada.

![Untitled](https://raw.githubusercontent.com/balta-io/blog/main/blazor-rotas-navegacao/images/Untitled 3.png)

💡 DICA Você não precisa seguir a mesma conveção das pastas no nome da URL. No exemplo acima, embora o arquivo Manage.razor esteja na pasta Admin/Account, sua URL não necessariamente precisa seguir este padrão, embora seja recomendado.

Links

O Blazor possui duas formas de criar links para páginas, o tradicional href do HTML e o NavLink, componente exclusivo do Blazor.

Em ambos os casos devemos referenciar o caminho (URL) até a nossa página, que no exemplo é a Counter.razor.

<a class="nav-link" href="/counter">
    Counter (Href)
</a>

Da mesma forma, podemos utilizar o NavLink, que é o componente de navegação padrão do Blazor e nos fornece alguns recursos adicionais.

<NavLink class="nav-link" href="counter">
    Counter (NavLink)
</NavLink>

NavLink

A maior diferença é que o NavLink verifica a rota que estamos e tem a possibilidade de adicionar alguma classe do CSS ao elemento em questão.

No caso, o NavLink tem a possibilidade de alternar uma classe CSS do elemento utilizando os atributos Match e ActiveClass.

Caso o atributo ActiveClass não seja definido, o NavLink por padrão atribuirá uma classe chamada active do CSS ao elemento.

<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
   Home
</NavLink>

Note que no href a “/” não está presente, isto por que estamos utilizando um template de rotas e ela se torna opcional.

Match

O atributor Match é um enumerador que possui dois valores, sendo eles All e Prefix, ambos utilizados para verificar a URL atual.

O NavLinkMatch.All define que a URL completa deve bater com o valor do href para que a classe active (Ou valor do ActiveClass) seja atribuído ao elemento.

Já o NavLinkMatch.Prefix define que a classe active (Ou valor do ActiveClass) deve ser aplicado quando o prefixo da URL bate com o valor href do elemento.

<li>
    <NavLink href="/pedidos"  Match="NavLinkMatch.Prefix">
        Pedidos
    </NavLink>
</li>
<li>
    <NavLink href="/pedidos/detalhes"  Match="NavLinkMatch.All">
        Detalhes do Pedido
    </NavLink>
</li>
<li>
    <NavLink href="/pedidos/editar"  Match="NavLinkMatch.All">
            Editar Pedido
    </NavLink>
</li>

No exemplo acima, quando o usuário navega para /pedidos, apenas o primeiro link fica ativo.

Quando o usuário navega para /pedidos/detalhes, o primeiro link permanece ativo, pois ainda corresponde ao prefixo da URL, e o segundo link também fica ativo porque corresponde a toda a URL.

Os valores dos parâmetros de rota são considerados para fins de correspondência de URLs, mas os valores e fragmentos da string de consulta são ignorados.

ActiveClass

O atributo ActiveClass permite adicionar uma classe (CSS) ao NavLink. Por padrão, uma classe chamada active é adicionada.

Para alterar esse valor padrão, basta informar o nome da classe (CSS) que deseja atribuir ao NavLink quando o Match for identificado.

<NavLink href="/pedidos"  Match="NavLinkMatch.Prefix">
    Pedidos
</NavLink>

No exemplo acima, como nenhum valor foi atribuído ao ActiveClass, uma classe chamada active será atribuída assim que navegarmos para /pedidos.

<NavLink href="/pedidos" ActiveClass="link-ativo" Match="NavLinkMatch.Prefix">
    Pedidos
</NavLink>

Já neste outro exemplo, como um valor foi atribuído ao ActiveClass, assim que navegarmos para /pedidos uma classe chamada link-ativo será adicionada ao NavLink.

NavigationManager

Para realizar a navegação através de um código C#, podemos utilizar o NavigationManage, injetando ele na página.

@page "/"
@inject NavigationManager navigationManager
<button @onlick="Navigate">Click</button>
@code{
    void Navigate()
    {
        navigationManager.NavigateTo("/other");
    }
}

Para realizar a navegação podemos utilizar algum dos métodos presentes no NavigationManager, como o NavigateTo e especificar uma URL.

FocusOnNavigate

Outro elemento que podemos encontrar é o FocusOnNavigate, presente no arquivo Routes.razor e que nos auxilia na seleção de elementos.

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(Layout.MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
    </Found>
</Router>

No exemplo acima, definimos que sempre após navegar para uma rota (Desde que ela exista), iremos selecionar o primeiro H1 (Headline) assim que a página for carregada.

Este comportamento nos ajuda na questão de usabilidade e acessibilidade, tornando mais fácil a navegação sem mouse ou simplesmente a rolagem da tela para uma sessão importante após a navegação.

Rotas em diferentes projetos

É possível ter componentes e páginas em projetos distintos, seja por motivo de reuso ou simplesmente uma organização do seu projeto.

Neste caso, podemos utilizar o AdditionalAssemblies para especificar projetos (Assemblies) adicionais ao atual.

<Router
    AppAssembly="@typeof(App).Assembly"
    AdditionalAssemblies="new[] { typeof(Component1).Assembly }">
    @* ... Router component elements ... *@
</Router>

Neste caso, o Blazor também buscará páginas em outros projetos especificados nesta propriedade.

Parâmetros de Rotas

Uma ação muito comum que temos é a passagem de parâmetros através das rotas durante a navegação.

No Blazor, assim como no Razor Pages, os parâmetros podem ser especificados através das chaves na URL.

@page "/route-parameter-1/{text}"

Posteriormente podemos atribuir (Binding) um parâmetro a uma propriedade simplesmente usando o atributo Parameter para decorá-la.

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

É importante frisar que o atributo Parameter só pode ser vinculado a propriedades. Variáveis não irão funcionar neste caso.

Em adicional, é importante manter o mesmo nome entre a propriedade e parâmetro para uma transição sem atritos. O exemplo final fica assim:

@page "/route-parameter-1/{text}"

<h1>Blazor is @Text!</h1>

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

Desta forma, ao chamarmos a URL https://localhost:xxxx/route-parameter-1/awesome teríamos o texto ”Blazor is awesome” escrito na tela.

Em contrapartida, ao tentar acessar a mesma URL anterior sem informar um parâmetro (https://localhost:xxxx/route-parameter-1), teríamos um erro 404, de página não encontrada.

Parâmetros opcionais

Como vimos no exemplo anterior, assim que declaramos um parâmetro em uma rota, ele se torna parte dela.

Desta forma, caso o parâmetro não seja informado, a rota se torna incompleta, sendo impossível acessá-la.

Assim como no C# temos os Nullable Types, aqui temos os parâmetros opcionais, onde podemos definir sua obrigatoriedade utilizando um ?.

@page "/route-parameter-1/{text?}"

Adicionando o ? ao fim do parâmetro, ele será declarado como Nullable, ou seja, se tornará opcional, tornando a URL https://localhost:xxxx/route-parameter-1 válida.

Vale lembrar que a URL https://localhost:xxxx/route-parameter-1/awesome também continua válida, visto que ela informa um parâmetro.

Para receber este parâmetro, é importante declarar a propriedade como Nullable também, já que o valor pode vir nulo e causar um NullReferenceException.

...
@code {
    [Parameter]
    public string? Text { get; set; }
}

Por fim, podemos fazer uso do método OnInitialized que é executado sempre que o componente é renderizado na tela.

Neste método podemos aproveitar para iniciarlizar nossa propriedade com algum valor caso nenhum parâmetro seja fornecido.

protected override void OnParametersSet()
{
    Text = Text ?? "awesome";
}

O código final do nosso componente fica conforme mostrado abaixo:

@page "/route-parameter-1/{text?}"

<h1>Blazor is @Text!</h1>

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

    protected override void OnInitialized()
    {
        Text = Text ?? "fantastic";
    }
}

Restrições de parâmetros

Além de especificar um parâmetro, podemos limitar seu tipo e adicionar algumas restrições a ele, facilitando ainda mais a validação.

Com as restrições de rotas, além de informar o parâmetro, caso o mesmo contenha alguma restrição, também será retornar o erro 404.

Para adicionar uma restrição ao parâmetro, basta especificar um tipo (Veja tabela adiante) após o uso do separador :.

@page "/user/{Id:int}"

Desta forma, se tentarmos abrir a URL /user/test, teríamos um erro 404, pois embora fora informado um parâmetro para o Id, o mesmo não é do tipo inteiro (Informamos test, uma string).

Abaixo encontra-se uma tabela com todas as restrições disponíveis e alguns exemplos de uso das mesmas.

Restrição Exemplo Validação Cultura invariante
bool true, FALSE No
datetime 2016-12-31, 2016-12-31 7:32pm Yes
decimal 49.99, -1,000.01 Yes
double 1.234, -1,001.01e8 Yes
float 1.234, -1,001.01e8 Yes
guid CD2C1638-1638-72D5-1638-DEADBEEF1638,  No
int 123456789, -123456789 Yes
long 123456789, -123456789 Yes

Restrições e parâmetros opcionais

É possível utilizar restrições de parâmetros e parâmetros opcionais juntos, só devemos nos atentar a ordem das sinalizações.

Neste caso, o sinalizador de parâmetro opcional (?) vem sempre no fim da rota, enquanto o sinalizador de restrição (:) permanece no mesmo local anterior.

@page "/user/{Id:int}/{Option:bool?}"

Catch All

Além dos parâmetros convencionais, existe o chamado Wildcard ou Coringa, que é representado por um asterisco (*).

Quando utilizamos o *, ignoramos todos os parâmetros e passamos a assumir apenas a URL atual.

@page "/catch-all/{*pageRoute}"

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

Desta forma, se chamássemos a URL /catch-all/this/is/a/test, todos os segmentos depois de catch-all seriam ignorados e o resultado da propriedade PageRoute seria this/is/a/test.

Este é um cenário para situações onde você quer ter uma segmentação na URL por conta de SEO mas quer manter uma mesma rota para um segmento todo.

Query Strings

Você com certeza já acessou algum site que na URL havia um ?chave=valor. Esta combinação é conhecida como Query String.

Desta forma, podemos passar parâmetros para nossas páginas que não afetam suas rotas, mas sim complementam a URL.

Por exemplo, podemos chamar a URL https://balta.io/busca?termo=SQL para informar um termo de busca via Query String.

// https://balta.io/busca/termo
//                       👆 -> Parâmetro via URL

// https://balta.io/busca?termo=SQL
//                       👆 -> Parâmetro via Query String

Diferente dos parâmetros de rota, quando utilizamos Query String, nossas rotas não precisam de nada especial.

@page "/busca"

Em adicional, precisamos do atributo SupplyParameterFromQuery, além do atributo Parameter que já vimos anteriormente.

@code {
    [Parameter]
    [SupplyParameterFromQuery]
    public string? Term { get; set; }
}

Desta forma, dizemos que estamos recebendo um parâmetro chamado Term e que este será recebido via Query String.

Agora ao chamar a URL https://balta.io/busca?termo=SQL teremos como resultado o texto Termo: SQL sendo exibido na tela.

O código completo desta página fica conforme exibido abaixo:

@page "/busca"

<h1>Exemplo de Busca</h1>

<p>Termo: @Term</p>

@code {
    [Parameter]
    [SupplyParameterFromQuery]
    public string? Term { get; set; }
}

Populares

Priority Queue

Priority Queue ou fila prioritária é um tipo de lista inclusa no C# 10 que permite que seus itens...


Implicit Operators no C#

Implicit Operators permitem adicionar comportamentos de conversão a objetos Built In ou complexos...


ASP.NET 5 – Autenticação e Autorização com Bearer e JWT

Este artigo atualmente utiliza a versão 5.0.0-rc.1 do ASP.NET/.NET, o que significa que ainda não...


Clean Code - Guia e Exemplos

Saiba como manter seu código limpo (Clean Code) seguindo algumas práticas sugeridas pelo Robert C...


Git e GitHub - Instalação, Configuração e Primeiros Passos

Git é um sistema de controle de versões distribuídas, enquanto GitHub é uma plataforma que tem o ...


Compartilhe este artigo



Conheça o autor

André Baltieri

André Baltieri

Microsoft MVP

Me dedico ao desenvolvimento de software desde 2003, sendo minha maior especialidade o Desenvolvimento Web. Durante esta jornada pude trabalhar presencialmente aqui no Brasil e Estados Unidos, atender remotamente times da ?ndia, Inglaterra e Holanda, receber 8x Microsoft MVP e realizar diversas consultorias em empresas e projetos de todos os tamanhos.





3.133

Aulas disponíveis

292

horas de conteúdo

76.461

Alunos matriculados

53.012

Certificados emitidos





Comece de graça agora mesmo!

Temos mais de 21 cursos totalmente de graça e todos com certificado de conclusão.

Começar


Prefere algo mais Premium?

Conheça nossos planos



Premium anual

Compra única, parcelada em até
12x no cartão de crédito


12x R$

99

,79

=R$ 1.197,44
  • 1 ano de acesso
  • Acesso à todo conteúdo
  • Emissão de Certificado
  • Tira Dúvidas Online
  • 67 cursos disponíveis
  • 10 carreiras disponíveis
  • 161 temas de tecnologia
  • Conteúdo novo todo mês
  • Encontros Premium

Começar agora

Política de privacidade



Precisa de ajuda?

Dúvidas frequentes



  • Posso começar de graça?

    Sim! Basta criar sua conta gratuita no balta.io e começar seus estudos. Nós contamos com diversos cursos TOTALMENTE gratuitos e com certificado de conclusão.

  • Vou ter que pagar algo?

    Nós temos cursos gratuitos e pagos, porém você não precisa informar nenhum dado de pagamento para começar seus estudos gratuitamente conosco. Os cursos gratuitos são completos e com certificado de conclusão, você não paga nada por eles.

    Porém, caso queira algo mais Premium , você terá acesso à diversos benefícios que vão te ajudar ainda mais em sua carreira.

  • Por onde devo começar?

    Siga SEMPRE as nossas Carreiras , elas vão te orientar em todos os sentidos. Os cursos já estão organizados em categorias e carreiras para facilitar seu aprendizado.
    Nossa sugestão para aprendizado é começar pelo Backend e seguindo para Frontend e Mobile.

    • Backend
    • Frontend
    • Mobile

  • Os cursos ensinam tudo que preciso?

    Nenhum curso no mundo vai te ensinar tudo, desculpa ser sincero! Os cursos são uma base, eles fornecem por volta de 30% do que você precisa aprender, o resto é com você, com dedicação e MUITA prática.

  • O que eu devo estudar?

    Java ou .NET? Angular ou React? Xamarin ou Flutter? A resposta é simples e direta: "Você já sabe o básico?"

    Se você ainda não sabe BEM o básico, ou seja, os fundamentos, OOP, SOLID, Clean Code, está perdendo tempo estudando Frameworks ou até coisas mais avançadas como Docker. Foque nos seus objetivos primeiro.
    Agora se você está indeciso sobre qual Framework estudar, a boa notícia é que o mercado neste momento está bem aquecido e você tem várias oportunidade. Desta forma o que levaríamos em conta para tomar esta decisão seria:

    • Já sei o básico
    • O Framework/Tecnologia tem mercado onde eu estou (região)
    • O Framework/Tecnologia é utilizado em uma empresa onde quero atual
    • O Framework/Tecnologia resolve meu problema
    • Eu gosto de utilizar o Framework/Tecnologia

  • Estou pronto para estudar no balta.io?

    Com certeza! O primeiro passo é começar e você pode fazer isto agora mesmo!

    Começar de graça

Ainda tem dúvidas?





Assine nosso Newsletter

Receba em primeira mão todas as nossas novidades.

Cadastrar


balta.io

Sobre

  • Como funciona?
  • Seja Premium
  • Agenda
  • Blog
  • Todos os cursos

Cursos

  • Frontend
  • Backend
  • Mobile
  • Fullstack

Suporte

  • Termos de uso
  • Privacidade
  • Cancelamento
  • Central de ajuda

Redes Sociais

  • Telegram
  • Facebook
  • Instagram
  • YouTube
  • Twitch
  • LinkedIn
  • Discord