dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.19k stars 9.93k forks source link

Page is refreshing when trying to use UriHelper.NavigateTo without pre-rendering feature #9757

Closed alexandrereyes closed 5 years ago

alexandrereyes commented 5 years ago

About the BUG: When you work without pre-rendering + page with parameters, UriHelper.NavigateTo doesn't work properly, the page refreshs.

  1. ASP.NET Core 3 preview 4
  2. If you only change the Blazor template a little (of course, disabling pre-rendering):
    
    @page "/fetchdata/{Id:int}"
    @using BlazorClientSide.Data
    @inject WeatherForecastService ForecastService

Weather forecast

This component demonstrates fetching data from a service.

@if (forecasts == null) {

Loading...

} else {

@foreach (var forecast in forecasts) { }
Date Temp. (C) Temp. (F) Summary
@forecast.Date.ToShortDateString() @forecast.TemperatureC @forecast.TemperatureF @forecast.Summary

}

@functions { WeatherForecast[] forecasts;

[Inject]
IUriHelper UriHelper { get; set; }

[Parameter]
public int Id { get; set; }

protected override async Task OnInitAsync()
{
    forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}

protected async override Task OnAfterRenderAsync()
{
    await base.OnAfterRenderAsync();
    UriHelper.NavigateTo("/");
}

}



notice the parameter Id and the `UriHelper.NavigateTo("/");`

4. See error
Browser will reload the page when hits `UriHelper.NavigateTo("/");`

### Expected behavior
The page can't refresh

### When pre-rendering is enable, it works properly
enetstudio commented 5 years ago

It seems to me that your Index.cshtml file is lacking document base uri : <base href="/" />. Perhaps not... In any case, the page is refreshed because the uri you try to navigate to is not within the URI space, and thus, as far as I recall, this leads to the default behavior of refreshing the page.

alexandrereyes commented 5 years ago

There is no cshtml, pre-rendering is off. We are using index.html

enetstudio commented 5 years ago

But do you have <base href="/" /> element in index.html ?

alexandrereyes commented 5 years ago

No, but why does this work without route parameter? I don't think it's about base href.

enetstudio commented 5 years ago

No, you don't... but did you try to add the base element to your HTML page ? It should be like this: <base href="/" />. Any SPA app should have this element added, as for instance, Angular... The following link is to the typescript code that control and regulate navigation: https://github.com/aspnet/AspNetCore/blob/master/src/Components/Browser.JS/src/Services/UriHelper.ts

I'm not one of the Blazor experts, my knowledge is quite limited, I am here to learn, and I may be proved wrong about what I'm saying, but, as far as I know, you can enable sort of prerendering in server-side Blazor apps by using the HTML helper method RenderComponentAsync : <app>@(await Html.RenderComponentAsync<App>(new { Name="Guest" }))</app>

In order to use this method, I guess, you've got to have a Razor Page (.cshtml), not HTML Page (.html). And the base element is configured like so: <base href="~/" /> See full sample: https://github.com/aspnet/AspNetCore/blob/master/src/Components/test/testassets/ComponentsApp.Server/Pages/Index.cshtml

Since RenderComponentAsync method prerenders the App Component, it actually prerender the whole Blazor app, but I called this "sort of prerendering" because I believe that there is much more for prerendering than this method.

Anyhow, if you use HTML Page (.html), it seems to me, that you can't use the RenderComponentAsync method at all, no ? If true, why did you say above that you've disabled prerendering when you actually can't and did not have the means (using the RenderComponentAsync method) to produce prerendering.

To sum up: In Razor Pages use <base href="~/" />, whereas in HTML Pages use <base href="/" /> . They might be interchangeable... I don't know. I've no way to verify this. But the base element is a must in an SPA app such as Blazor or Angular. Again, see UriHelper.ts, and most importantly, it has nothing to do with prerendering.

Hope this helps...

alexandrereyes commented 5 years ago

oh! This was the issue, everything is working fine now! Tks @enetstudio