Author : HASSAN MD TAREQ

Just to simplify in layman’s term

  • Routing: following framework convention and using syntax (route template) to configure how view/page/component will respond to HTTP request
  • Navigation: changing browser urls for different views/pages/components
  • Route path mapping: mapping URL segment to parameter (property/’method param’)
  • URL parameter mapping: parsing and extracting values from query strings

Mapping Route Path

Foo.razor

@page "/foos/{Id:int}"
@inherits FooBase

// ... ... ...

Foo.razor.cs

public class FooBase: ComponentBase
{
	[Parameter]
	protected int Id { get; set; }
	
	[Inject]
	protected FooContext _context { get; set; }

	protected List<Foo> foo;

	protected override async Task OnInitializedAsync()
	{
		foo = await _context.Bars.FindAsync(Id);
	}
}

Mapping URL Parameter

  • The query string of a request can be obtained from the NavigationManager’s Uri property:
  • To parse a query string’s parameters:
    • Add a package reference for Microsoft.AspNetCore.WebUtilities
    • Obtain the value after parsing the query string with QueryHelpers.ParseQuery

Assume requested URI: /items?count=15

Items.razor

@page "/items"
@inherits ItemsBase

// ... ... ...

Items.razor.cs

using Microsoft.AspNetCore.WebUtilities

public class ItemsBase: ComponentBase
{

	[Inject]
	protected ItemContext _context { get; set; }

	protected List<Item> fixedNumberOfItems;

	protected override void OnInitialized() // no need for async here
	{
        var query = new Uri(NavigationManager.Uri).Query;

        if (QueryHelpers.ParseQuery(query).TryGetValue("count", out var count))
        {
            fixedNumberOfItems = _context.Bars.Take(count);
        }
	}
}

Details Page for Composite Primary Key

Items.razor

@page "/items"
@inject NavigationManager NavigationManager

// ... ... ...

    <table class="table">
        <thead>
            <tr>
                <th>XXX</th>
                <th>YYY</th>
                <th>Foo</th>
                <th>Bar</th>
                <th colspan="2">Action</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in items)
            {
                <tr>
                    <td>@item.XXX</td>
                    <td>@item.YYY</td>
                    <td>@item.Foo</td>
                    <td>@item.Bar</td>
                    <td>
                        <button class="btn btn-danger" @onclick="@( () => NavigationManager.NavigateTo($"items/{item.Foo}.{item.Bar}") )">
                            Details
                        </button>
                    </td>
                </tr>
            }
        </tbody>
    </table>

// ... ... ...

ItemDetails.razor (requested uri: “/items/xfoo.zbar”)

@page "/items/{CompositeKey}"
@inject NavigationManager NavigationManager

<h2>Details</h2>

<br />

<div class="col-md-12">
    <table class="table">
	
        <tr>
            <td>XXX</td>
            <td>@item.XXX</td>
        </tr>
        <tr>
            <td>YYY</td>
            <td>@item.YYY</td>
        </tr>
		
        // ... ... ...
		
    </table>
</div>

// ... ... ...

ItemDetails.razor.cs

using Microsoft.AspNetCore.WebUtilities

public class ItemDetailsBase: ComponentBase
{

  [Parameter]
  public string CompositeKey { get; set; }
	
  [Inject]
  protected ItemContext _context { get; set; }

  protected Item item;

  protected override async Task OnInitializedAsync()
  {
    item = await _context.Items.FindAsync(CompositeKey.Split("."));
  }
	
  // ... .... ...
}