Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Building Blazor WebAssembly Applications with gRPC

You're reading from   Building Blazor WebAssembly Applications with gRPC Learn how to implement source generators and gRPC in your Blazor apps for better performance

Arrow left icon
Product type Paperback
Published in Nov 2022
Publisher Packt
ISBN-13 9781804610558
Length 196 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Author (1):
Arrow left icon
Václav Pekárek Václav Pekárek
Author Profile Icon Václav Pekárek
Václav Pekárek
Arrow right icon
View More author details
Toc

Table of Contents (10) Chapters Close

Preface 1. Chapter 1: Introducing Blazor, gRPC, and Source Generators 2. Chapter 2: Creating a Blazor WebAssembly Application FREE CHAPTER 3. Chapter 3: Creating a Database Using Entity Framework Core 4. Chapter 4: Connecting Client and Server with REST API 5. Chapter 5: Building gRPC Services 6. Chapter 6: Diving Deep into Source Generators 7. Chapter 7: Best Practices for C# and gRPC 8. Index 9. Other Books You May Enjoy

Understanding page routing in Blazor

Blazor WebAssembly is a SPA. This means that routing is not done on the server but the client. While clicking on the link updates the address bar of the browser, the page itself is not refreshed. Blazor finds a component with a matching route in the @page directive and renders this component (and all child components) as a page.

The Router component takes care of resolving the correct component to render. This component is typically used in the application root component – that is, App.razor. The component is created from two RenderFragments, as follows:

<Router AppAssembly="@typeof(App).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData"
          DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData"
          Selector="h1" />
    </Found>
    <NotFound>
        <PageTitle>Not found</PageTitle>
        <LayoutView Layout="@typeof(MainLayout)">
            <p role="alert">Sorry, there's nothing at this
              address.</p>
        </LayoutView>
    </NotFound>
</Router>

In the preceding code, you can see the Router component with the Found and NotFound sections. The Router component looks to the specified AppAssembly and discovers all routable components (components with the @page directive). When navigating from one page to another, the Router component renders the Found section, if there is any routable component with a matched route. Otherwise, the NotFound section is rendered.

Rendering of the component is handled in the RouteView component. The RouteData parameter of the component contains information about the matched component. RouteView uses a layout defined on the component’s @layout directive, or DefaultLayout if the component layout is not specified.

The FocusOnNavigate component is not required. This component sets focus on the element specified by the CSS selector in the Selector parameter. It is useful when building websites compatible with screen readers, or when you want to focus on some user input fields after changing the page.

Navigating between pages

To navigate between pages, the standard HTML anchor is used:

<a href="/contacts">Contacts</a>

As shown in the preceding code, there is no difference between page navigation in standard HTML and Blazor. That is one of Blazor’s advantages over other JavaScript SPA frameworks, which use the custom component to provide SPA navigation. Blazor intercepts any navigation on the same site and tries to find the corresponding components to render.

If you need to manipulate the address from the C# code, you must inject NavigationManager into your code, as follows:

@page "/offers"
@inject NavigationManager NavManager
…
<button @onclick="GoToContacts">Contacts</button>
@code {
  void GoToContacts()
  {
    NavManager.NavigateTo("contacts");
  }
}

The preceding code will change the page to /contacts after the button is clicked.

Page directive

The @page directive can be specified multiple times in the component. It can also contain dynamic parts of the URL:

PageDirective.razor

@page "/author"
@page "/author/{Name}"
<h1>Author @authorName </h1>
@code {
  private string authorName;
[Parameter]
  public string Name { get; set; }
  
  protected override void OnInitialized()
  {
    authorName = Name ?? "Not set";
  }
}

In the preceding code, the first @page directive specifies the URL without any parameters. The second @page directive specifies a parameter with the name. The following URLs are valid for the PageDirective component:

  • /author
  • /author/John
  • /author/123

In the third example, /author/123, you can see that we can pass numbers to the text parameter. It is fine here because any value can be treated like a string. But what if we expect a different type?

Route constraints

Route constraints are used when you need to enforce a specific data type of the route parameter. The route constraints are defined the same way as in C# API endpoints – that is, by adding a semicolon after the parameter name and then specifying the data type:

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

The preceding code will define the URL for the author with Id as an integer.

Not all constraints are supported at the time of writing. The following table shows the supported types:

Constraint type

Example of constraint

Example of valid values

bool

@page "/user/{enabled:bool}

True, true, FALSE

datetime

@page "/user/{createdAt:datetime}

2022-04-23, 2022-01-01 6:18am

decimal

@page "/basket/{price:decimal}

59.99, -999.99

double

@page "/package/{weight:double}

1.15, -39.12

float

@page "/package/{weight:float}

1.234, -1.234

guid

@page "/user/{id:guid}

905E47D7-DA48-4301-8137-B25541438240, {FEB6A90F-3D25-46D1-AD62-64BBD499A0D6}

int

@page "/user/{id:int}

123456, -123456

long

@page "/timer/{ticks:long}

123456789, -123456789

Table 2.2 – Blazor router supported constraints

Component route parameters can also be marked as optional:

@page "/user/{id:int}/{valid:bool?}"

The preceding code specifies the URL to /user with the required Id parameter and optional Valid bool parameter. The optional ? symbol can also be used without type constraints.

Catch-all parameters

Sometimes, you may need to create components for multiple routes. In that case, a catch-all parameter can be used:

Posts/AllPosts.razor

@page "/posts/{*pageRoute}"
@code {
  [Parameter]
  public string? PageRoute { get; set; }
}

The preceding code shows a catch-all parameter named PageRoute. The catch-all route parameter must be of the string type and placed at the end of the route; it is not case-sensitive.

The PageRoute parameter will contain all the matched values from the URL:

  • For the /posts/animals/africa/forest URL, the PageRoute value is animals/africa/forest
  • For the /posts/animals URL, the PageRoute value is animals
  • For the /posts/animals/europa%2Fwater URL, the PageRoute value is animals/europa/water

With that, we know how to create components and how to navigate between them. In the next section, we will look at the project we will be creating in this book. And yes! We will use everything we’ve learned in this chapter up until this point.

You have been reading a chapter from
Building Blazor WebAssembly Applications with gRPC
Published in: Nov 2022
Publisher: Packt
ISBN-13: 9781804610558
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime