Blazor - How to get layout @Body path?

Viewed 547

I am solving problem with breadcrumb navigation and dynamic showing (I want to avoid have in every razor component (one of Pages) static data. Thank you in forward.

Problem: how to get path of the @Body component? In the body is of course the one of (default folder name in project) Pages. So line 1 of "body itself" is @page "/somePage"...

My (shortened) layout:

<div class="page">
    <div class="main">
        <div class="top-row TitleButtonList @((closedLeftBar) ? "TitleButtonListClose" : "") ">
            <TitleButton />
        </div>
        <div class="top-row">
            <BreadcrumbNav breadCrumbData="breadCrumbDatas"></BreadcrumbNav>
            <p>Error test name: @path</p>
        </div>

        <div class="content px-4 @((closedLeftBar) ? "contentClose col-md-10" : "contentOpen col-md-9")">
            @Body
            <FOLButtons />
        </div>
    </div>
</div>

@code {
    public List<BreadCrumbData> breadCrumbDatas;
    string path = string.Empty;

    protected override void OnInitialized()
    {
        breadCrumbDatas = breadCrumbService.GetProperList();
        path = ??????
    }
}

Model of BreadCrumb:

public class BreadCrumbData
    {
        [Required]
        public string Text { get; set; }
        [Required]
        public string URL { get; set; }
        [Required]
        public int Level { get; set; }

        [Required]
            #nullable enable
        public string? ParentURL { get; set; }

        public BreadCrumbData(string text, string url, int level, string parentURL)
        {
            Text = text;
            URL = url;
            Level = level;
            ParentURL = parentURL;
        }
    }

Breadcrumb component (that one what is in layout)

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
        @if (breadCrumbData != null)
        {

            @foreach (var item in breadCrumbData)
            {
                @if (item == breadCrumbData.Last())
                {
                    <li class="breadcrumb-item active" aria-current="page">@item.Text</li>

                }
                else
                {
                    <li class="breadcrumb-item"><a href="@item.URL">@item.Text</a></li>
                }
            }
        }
    </ol>
</nav>

@code {
    [Parameter]
    public List<BreadCrumbData> breadCrumbData { get; set; }
}
2 Answers

Blazor provides the NavigationManager for this purpose (see Blazor routing):

@inject NavigationManager NavigationManager;

protected override void OnInitialized()
{
    breadCrumbDatas = breadCrumbService.GetProperList();

    // Get everything after the domain + '/' (e.g. after "https://example.com/")
    path = NavigationManager.Uri.Substring(Navigator.BaseUri.Length); 

    // You can also listen for a path change by subscribing to 
    //     NavigationManager.LocationChanged.
}

A couple notes/suggestions:

  • Since NavigationManager can be injected, you don't need to pass it down to your BreadCrumbs component as a parameter (unless you are using the component for something other than URL paths). You can directly inject it into your BreadCrumbs component:
@inject NavigationManager NavigationManager;

<nav aria-label="breadcrumb">
    <ol class="breadcrumb">
  • @Body isn't a component: it is a RenderFragment.
  • @Body doesn't have a path, per se; pages (designated with @page) do. Routing is managed by App.razor and configured in Startup.cs.

You can get the current page URI from the NavigationManager.Uri property, by injecting NavigationManager. From that, you can extract your data.

Related