I created a new Blazor Server Side Application in Preview 8. When I call the UriHelper.NavigateTo to go to the counter page from the Index.razor page, the counter page is c
Update due to a comment by dani herrera:
The life cycle method OnInitializedAsync is called twice, but the counter @page component is called once only.
This behavior is by design. The first time OnInitializedAsync is executed is when server-side Blazor app is being pre-rendering, during which time, JSInterop is not available, and thus calling UriHelper.NavigateTo("/counter");
triggers an error. The following code snippet describe how Blazor currently treats such cases:
protected override void NavigateToCore(string uri, bool forceLoad)
{
Log.RequestingNavigation(_logger, uri, forceLoad);
if (_jsRuntime == null)
{
var absoluteUriString = ToAbsoluteUri(uri).ToString();
throw new NavigationException(absoluteUriString);
}
_jsRuntime.InvokeAsync<object>(Interop.NavigateTo, uri, forceLoad);
}
See more here. As you may realize, the counter @page component is not called, and an exception is raised.
After pre-rendering has completed, client-side SignalR establishes a connection to the server, and your app is rendered. This time (second time the method OnInitializedAsync is called) UriHelper.NavigateTo("/counter");
is properly executed, and we are happily navigated to the counter page (first time)
You may use the method OnAfterRender as a workaround, and you should verify whether a connection with the server has already been established by SignalR; that is the pre-rendering process has completed.
@page "/"
@using Microsoft.JSInterop
@inject IComponentContext ComponentContext
@inject IJSRuntime jsRuntime
<p>Navigate to the counter component.</p>
@code{
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!ComponentContext.IsConnected) return;
UriHelper.NavigateTo("/counter");
}
}
Hope this helps...
This behavior is because the pre-render feature. Notice that, when you are on counter page
(loaded for twice), if you click on Home
, only one execution is fired:
When pre-render is enabled (by default), the prerended page's OnInitializedAsync
is called for twice by design. For this reason, your redirect statement is executed for twice.
To test is I wrote this code on index OnInitializedAsync
:
@page "/"
@inject IUriHelper UriHelper
<h1>Hello, world!</h1>
Welcome to your new app.
@code{
protected async override Task OnInitializedAsync()
{
System.Console.WriteLine("_* ");
System.Console.WriteLine("_**************************");
System.Console.WriteLine("_***** Pre render ******");
System.Console.WriteLine("_**************************");
System.Console.WriteLine("_ ");
return;
}
}
And I call the page using pre-render and from the app (without prerender). Noticed that when I force reload (prerended) the OnInitializedAsync
is executed for twice:
Learn more about render modes.