简体   繁体   中英

How to access current route using Blazor component

I have an ASP(dot)NET web app that has a simple navbar, I am trying to use a Blazor component that will alter the navbar and increase the width of the left border if the page happens to be the active page. So far I am using a switch statement that will switch based on the current page which is represented by a string. My problem is that I cannot find a way to programmatically find the current URL that the site is on. I have searched up this question multiple times and each solution has not worked for me, using HttpContext has not worked either.

switch (CurrUrl)
{
case "Index":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li id="CurPage">Home</li>
                    <li class="menu-item">Shop</li>
                    <li class="menu-item">FAQ</li>
                    <li class="menu-item">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
case "Shop":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li class="menu-item">Home</li>
                    <li id="CurPage">Shop</li>
                    <li class="menu-item">FAQ</li>
                    <li class="menu-item">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
case "FAQ":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li class="menu-item">Home</li>
                    <li Class="menu-item">Shop</li>
                    <li id="CurPage">FAQ</li>
                    <li class="menu-item">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
case "About":
    <header>
        <div>
            <nav>
                <ul class="main-menu">
                    <li class="menu-item">Home</li>
                    <li class="menu-item">Shop</li>
                    <li class="menu-item">FAQ</li>
                    <li id="CurPage">About</li>
                </ul>
            </nav>
        </div>
    </header>
    break;
}

@code {
    string CurrUrl = null;
}

How to access current route using Blazor component

This title is misleading and you should change it. You can't access the the current route in order to do that task, as the current route does not exist yet

I have searched up this question multiple times and each solution has not worked for me, using HttpContext has not worked either.

Again, the solution is not by using the current route as no route has already been created. Your components are not yet created, so no route is available

HttpContext is not available in Blazor, most of the time, if at all...

Solution:

Add this code to the MainLayout component

  1. Define a property of type Type. This property will be populated with the Type ( component) that is going to be created

  2. You can retrieve the type of the component from the OnParametersSet method of the MainLayout component

  3. When you start your project, the Type is Index (Note that it is returned in the form: <projectname>.Pages.Index)

  4. If you type in your browser the url of your app + "/counter", as for instance: https://localhost:44373/counter , you'll get <projectname>.Pages.Counter


 @code{

     public Type PageType { get; set; }

     protected override void OnParametersSet()
    {
    
       PageType = (this.Body.Target as RouteView)?.RouteData.PageType;

       Console.WriteLine("This is your type (current type)" + 
                                                      PageType);
    }
  }

At the top of the MainLayout.razor file the <NavMenu /> is instantiated. Add to it an attribute parameter named PageType, as follows:

<NavMenu PageType="@PageType" />

The PageType on the left side should be defined in the NavMenu component. As you can see it is bound to the PageType property defined in MainLayout.

Now you should define the parameter property named PageType in NavMenu like this:

NavMenu.razor

@code {
    [Parameter]
    public Type PageType { get; set; }
} 

Now, you have the current Type (component) available in your NavMenu component, and you can use it as you please.

It is essential that you understand how components are rendered... which comes first, next etc. And much much more...

But hey, you're going to have tough time managing your task... The following code snippet demonstrates, very roughly that what you intend to do is workable( My code is fine and does the job, and the issues you're going to have are not related to it).

NavMenu.razor

<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
       
    @switch (PageType.ToString())
    {
        case "BlazorApp4.Pages.Index":
            @*<header>
                    <div>
                        <nav>
                            <ul class="main-menu">
                                <li id="CurPage">Home</li>
                                <li class="menu-item">Shop</li>
                                <li class="menu-item">FAQ</li>
                                <li class="menu-item">About</li>
                            </ul>
                        </nav>
                    </div>
                </header>*@

            <ul class="nav flex-column">
                <li class="nav-item px-3">
                    <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
                        <span class="oi oi-home" aria-hidden="true"></span> Home
                    </NavLink>
                </li>
                <li class="nav-item px-3">
                    <NavLink class="nav-link" href="counter">
                        <span class="oi oi-plus" aria-hidden="true"></span> Counter
                    </NavLink>
                </li>
                <li class="nav-item px-3">
                    <NavLink class="nav-link" href="fetchdata">
                        <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
                    </NavLink>
                </li>
            </ul>
            break;
        case "Shop":
            <header>
                <div>
                    <nav>
                        <ul class="main-menu">
                            <li class="menu-item">Home</li>
                            <li id="CurPage">Shop</li>
                            <li class="menu-item">FAQ</li>
                            <li class="menu-item">About</li>
                        </ul>
                    </nav>
                </div>
            </header>
            break;
        case "FAQ":
            <header>
                <div>
                    <nav>
                        <ul class="main-menu">
                            <li class="menu-item">Home</li>
                            <li Class="menu-item">Shop</li>
                            <li id="CurPage">FAQ</li>
                            <li class="menu-item">About</li>
                        </ul>
                    </nav>
                </div>
            </header>
            break;
        case "About":
            <header>
                <div>
                    <nav>
                        <ul class="main-menu">
                            <li class="menu-item">Home</li>
                            <li class="menu-item">Shop</li>
                            <li class="menu-item">FAQ</li>
                            <li id="CurPage">About</li>
                        </ul>
                    </nav>
                </div>
            </header>
            break;
    }
</div>  

The code above is going to display the default links to the default template pages, when you start your page. (Index page). Comment out the code in the case "BlazorApp4.Pages.Index: , and uncomment your code (...) located under case "BlazorApp4.Pages.Index":

Lo and behold, total darkness... here comes your pains...work hard...good luck.

You can get the current URL from the navigation manager.

@page "/navigate"
@inject NavigationManager NavigationManager

@code {
   string CurrUrl = null;
   protected override void OnInitialized()
   {
       CurrUrl = NavigationManager.Uri.ToString();
   }
}

Docs

I used

<CascadingValue Name="RouteData" Value="routeData"> ... </CascadingValue>

in App.Razor to make de current routeData available to all components as a cascading parameter.

[CascadingParameter(Name = "RouteData")]
public RouteData? RouteData { get; set; }

RouteData has a property 'PageType' which contains the type of the currently routed Page-component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM