最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

asp.net core - Why doesn't NavigationManager.Uri seem to update itself on .NavigateTo(string)? - Stack Overflow

programmeradmin3浏览0评论

If I do the following:

@page "/mypage"
@inject NavigationManager NavigationManager
<button @onclick="ts">nav to a random fragment</button>
@code{
  private void ts()
  {
     NavigationManager.NavigateTo($"/mypage#{Guid.NewGuid()}");
     StateHasChanged();
     Console.WriteLine(NavigationManager.Uri);
  }
}

I expect to see a different Guid in both the browser URL bar and in the console every time I click the button. I actually see that the browser URL changes properly but the URL written to the console never does.

Why is NavigationManager.Uri seemingly blatantly wrong? What can I do to get the current URL after I've changed its fragment?

I also tried modifying ts() to the following, which didn't help.

    private async Task ts()
    {
        NavigationManager.NavigateTo($"mypage#{Guid.NewGuid()}");
        StateHasChanged();
        await Task.Delay(1);
        Console.WriteLine(NavigationManager.Uri);
    }

On .NET 9; RenderMode is InteractiveWebAssembly.

If I do the following:

@page "/mypage"
@inject NavigationManager NavigationManager
<button @onclick="ts">nav to a random fragment</button>
@code{
  private void ts()
  {
     NavigationManager.NavigateTo($"/mypage#{Guid.NewGuid()}");
     StateHasChanged();
     Console.WriteLine(NavigationManager.Uri);
  }
}

I expect to see a different Guid in both the browser URL bar and in the console every time I click the button. I actually see that the browser URL changes properly but the URL written to the console never does.

Why is NavigationManager.Uri seemingly blatantly wrong? What can I do to get the current URL after I've changed its fragment?

I also tried modifying ts() to the following, which didn't help.

    private async Task ts()
    {
        NavigationManager.NavigateTo($"mypage#{Guid.NewGuid()}");
        StateHasChanged();
        await Task.Delay(1);
        Console.WriteLine(NavigationManager.Uri);
    }

On .NET 9; RenderMode is InteractiveWebAssembly.

Share Improve this question edited Apr 1 at 13:05 Patrick Szalapski asked Mar 31 at 19:54 Patrick SzalapskiPatrick Szalapski 9,44812 gold badges82 silver badges153 bronze badges 2
  • I can't repro this exactly. I see the NavigationManager.Uri changing but 1 step behind. As always, specify Version(s) and RenderMode. – Henk Holterman Commented Apr 1 at 10:05
  • Thanks, Henk. Did so. On .NET 9; RenderMode is InteractiveWebAssembly. – Patrick Szalapski Commented Apr 1 at 13:06
Add a comment  | 

2 Answers 2

Reset to default 1

Fragment changes (#...) do not trigger a full navigation event in Blazor. Then NavigationManager.Uri does not reflect the new fragment until another navigation event happens. You could use JS interop to get to current URL.

@page "/mypage"
@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager

<button @onclick="ts">nav to a random fragment</button>

@code {
    private async Task ts()
    {
        var newUrl = $"/mypage#{Guid.NewGuid()}";
        NavigationManager.NavigateTo(newUrl);
        var currentUrl = await JSRuntime.InvokeAsync<string>("eval", "window.location.href");
        Console.WriteLine(currentUrl);
    }
}

Your attempt with Task.Delay(1) was close. But things have changed, a 1ms delay isn't enough anymore. I think that Delay() got more 'accurate', not rounding up the value. Or something.

This will basically work:

    private async Task ts()
    {
        NavigationManager.NavigateTo($"mypage#{Guid.NewGuid()}");
        StateHasChanged();
        await Task.Delay(10);  // adapt to taste ...
        Console.WriteLine(NavigationManager.Uri);
    }

It's all because the NavigationManager is updated on (after) a Render. So the better, more reliable approach is to catch the value in OnAfterRender and build some change detecting logic there to use it.
You would then not need StateHasChanged() or Delay().

发布评论

评论列表(0)

  1. 暂无评论