【问题标题】:Get current URL in a Blazor component获取 Blazor 组件中的当前 URL
【发布时间】:2018-10-10 16:18:30
【问题描述】:

我需要知道当前页面的 URL 以检查是否必须将某种样式应用于元素。下面的代码就是一个例子。

    @using Microsoft.AspNetCore.Blazor.Services
    @inject IUriHelper UriHelper
    @implements IDisposable

    <h1>@url</h1>
    <nav>
        <div class="nav-wrapper">
            <a href="#" class="brand-logo">Blazor</a>
            <ul id="nav-mobile" class="right hide-on-med-and-down">
                <li>
                    <NavLink href="/" Match=NavLinkMatch.All>
                        Home
                    </NavLink>
                </li>
                <li>
                    <NavLink href="/counter">
                        Counter
                    </NavLink>
                </li>
                <li>
                    <NavLink href="/fetchdata">
                        Fetch data
                    </NavLink>
                </li>
            </ul>
        </div>
    </nav>

    @functions {

        private string url = string.Empty;

        protected override void OnInit()
        {
            url = UriHelper.GetAbsoluteUri();
            UriHelper.OnLocationChanged += OnLocationChanged;
        }

        private void OnLocationChanged(object sender, LocationChangedEventArgs e)
        {
            url = newUriAbsolute;
        }

        public void Dispose()
        {
            UriHelper.OnLocationChanged -= OnLocationChanged;
        }
    }

我使用了与 Blazor 存储库中的 NavLink 组件相同的方法,但它不起作用。有什么想法吗?。

【问题讨论】:

  • GetAbsoluteUri() 对我有用,到底是什么问题?

标签: c# asp.net-core blazor


【解决方案1】:

连接到页面或组件中的OnLocationChanged 事件是没有用的,因为它们是按需加载和处置的。

您应该在 app.cshtml 中注册此事件,因为它不会被释放。

【讨论】:

    【解决方案2】:

    您应该听 IUriHelper 的 LocationChange,它会触发函数执行您想要的操作,例如:

    @using Microsoft.AspNetCore.Blazor.Components
    @using Microsoft.Extensions.Logging
    @inject Microsoft.AspNetCore.Blazor.Services.IUriHelper UriHelper
    @inject ILogger<NavItem> logger
    
    <li class="m-menu__item @(Active ? "m-menu__item--active" : "")">
        <a href=@Url class="m-menu__link ">
            <span class="m-menu__item-here"></span>
            <i class="m-menu__link-icon @Icon"></i>
            <span class="m-menu__link-text">@Text</span>
        </a>
    </li>
    
    @functions {
        protected override void OnInit()
        {
            UriHelper.OnLocationChanged += OnLocationChanges;
        }
        [Parameter]
        private string Url { get; set; }
        [Parameter]
        private string Icon { get; set; }
        [Parameter]
        private string Text { get; set; }
        private bool Active = false;
        private void OnLocationChanges(object sender, string newLocation)
        {
            bool active = newLocation.Contains(Url);
            if(active != Active) //Only re-render the components that need it
            {
                Active = active;
                StateHasChanged();
                logger.LogInformation("Location Change To:" + newLocation);
            }
        }
    }
    

    【讨论】:

    • 此 UriHelper.OnLocationChanged 事件具有新参数,导致此示例与 .netCore 3 preview6 出现错误。应该是:private void OnLocationChanges(object sender, LocationChangedEventArgs e)
    • 这个答案是针对过时版本的 blazor,现在使用 NavigationManager。
    【解决方案3】:

    使用 NavigationManager 类中的 Uri 属性。

    工作原理

    .razor 页面上使用之前从注入中获取它:

    @inject NavigationManager MyNavigationManager
    

    如果您更喜欢“代码隐藏”体验,或者在 .cs 文件中这样写:

    using Microsoft.AspNetCore.Components;
    ...
    [Inject]
    public NavigationManager MyNavigationManager {get; set;}
    

    样本

    @page "/navigate"
    @inject NavigationManager MyNavigationManager
    
    <h1>Current URL</h1>
    
    <p>@(MyNavigationManager.Uri)</p>
    
    

    有关导航(NavigateTo、BaseUri、ToAbsoluteUri、ToBaseRelativePath、...)的更多信息:URI and navigation state helpers

    NavigationManager 备忘单

    MyNavigationManager.Uri
    #> https://localhost:5001/counter/3?q=hi
    
    MyNavigationManager.BaseUri
    #> https://localhost:5001/
    
    MyNavigationManager.NavigateTo("http://new location")
    #> Navigates to new location
    
    MyNavigationManager.LocationChanged
    #> An event that fires when the navigation location has changed.
    
    MyNavigationManager.ToAbsoluteUri("pepe")
    #> https://localhost:5001/pepe
    
    MyNavigationManager.ToBaseRelativePath(MyNavigationManager.Uri)
    #> counter/3?q=hi
    
    Helper: AddQueryParm( "q2", "bye" ) // (*1)
    #> https://localhost:5001/counter/3?q=hi&q2=bye
    
    Helper: GetQueryParm( "q" )
    #> hi
    

    (*1) Net6 介绍GetUriWithQueryParameter。更多信息:Manipulate the query string from Blazor

    助手代码:

    @code {
    
        [Parameter]
        public string Id { get; set; }
    
        // Blazor: add parm to URL
        string AddQueryParm(string parmName, string parmValue)
        {
            var uriBuilder = new UriBuilder(MyNavigationManager.Uri);
            var q = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
            q[parmName] = parmValue;
            uriBuilder.Query = q.ToString();
            var newUrl = uriBuilder.ToString();
            return newUrl;
        }
    
        // Blazor: get query parm from the URL
        string GetQueryParm(string parmName)
        {
            var uriBuilder = new UriBuilder(MyNavigationManager.Uri);
            var q = System.Web.HttpUtility.ParseQueryString(uriBuilder.Query);
            return q[parmName] ?? "";
        }
    
    }
    

    【讨论】:

    • 从 v0.8.0 开始,使用服务器端模式时应使用:@inject Microsoft.AspNetCore.Components.Services.IUriHelper UriHelper,使用客户端模式时应使用:@inject Microsoft.AspNetCore.Blazor.Services.WebAssemblyUriHelper UriHelper
    • @Henry Rodriguez,不,你错了。正确的方法是注入IUriHelper,而不是实现..
    • 如果用户试图通过 Url 地址强制进入另一个页面,则它不起作用
    猜你喜欢
    • 2020-06-01
    • 2023-02-01
    • 2020-11-16
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 2011-01-30
    相关资源
    最近更新 更多