Create new blazor project with dotnet new blazor
. Modify Index.cshtml
:
@page "/"
@page "/{Id}"
<h1>Id = @Id</h1>
<p><a href="/">Without Id</a></p>
<p><a href="/15">With Id = 15</a></p>
@functions {
[Parameter]
public string Id { get; set; }
}
Run application.
When I click With Id = 15
link, everything works as expected - url has changed, parameter {Id}
is assigned to value Id
, all good.
But when I click Without Id
link after that, url has changed, but my Id stays the same - equal 15.
Why my value didn't change? What am I missing here? How can I fix this?
By using Blazor route parameters, you can pass values from one page to another page. Use NavigationManager to pass a value and route the parameter to another page. Follow this example to achieve passing values from one page to another. Get the passed Page1 parameter value in Page2.
The easiest way is to use Route parameters instead of QueryString: @page "/navigatetopage/{id:int}/{key}" @code { [Parameter] public int Id{get;set;} [Parameter] public string Key{get;set;} ... }
Access to browser navigation from Blazor is provided via the NavigationManager service. This can be injected into a Blazor component using @inject in a razor file, or the [Inject] attribute in a CS file. The NavigationManager service has two members that are of particular interest; NavigateTo and LocationChanged .
You can redirect to a page in Blazor using the Navigation Manager's NavigateTo method. In the following code snippet, it will redirect to the home page when this page gets loaded. Similarly, you can call NavigateTo() method from NavigationManager class anywhere to redirect to another page.
Optional route parameters are supported as of ASP.NET Core 5.0.
For example:
@page "/RouteParameter/{text?}"
<h1>Blazor is @Text!</h1>
@code {
[Parameter]
public string Text { get; set; }
protected override void OnInitialized()
{
Text = Text ?? "fantastic";
}
}
This behavior is by design. Note that a changed url does not imply that the current page has changed. The following JavaScript function performs the internal navigation which changes the url:
function performInternalNavigation(absoluteInternalHref: string) {
history.pushState(null, /* ignored title */ '', absoluteInternalHref);
handleInternalNavigation();
}
Source: https://github.com/aspnet/AspNetCore/blob/93127b39e824181d4f9b1a62b6fc8d10c481e2c8/src/Components/src/Microsoft.AspNetCore.Components.Browser.JS/src/Services/UriHelper.ts
Calling history.pushState causes the URL bar to display ".../15", but won't cause the browser to load the new url, or rather cause Blazor to recreate the Index component. Blazor does not recreate a component if only the URL parameters change. Since you are already on the Index page, clicking on the link "Without Id", does not cause the Index Component to re-render. The current Component instance is reused instead, but alas this instance component has its parameter property set to the value of 15, and it is not overwritten by the AssignToProperties method which "Iterates through the ParameterCollection, assigning each parameter to a property of the same name on target." But the ParameterCollection does not contain an Id parameter; recall that this occurs after you hit the "Without Id". The end result, again, is having the parameter property Id containing the value 15. Source: https://github.com/aspnet/Blazor/blob/29f925852b0a5e81e82780e0c1c32b486f7c3be6/src/Microsoft.AspNetCore.Blazor/Components/ParameterCollectionExtensions.cs
Workarounds to solve this issue:
public override void SetParameters(ParameterCollection parameters)
{
if (string.IsNullOrEmpty(parameters.GetValueOrDefault<string>("Id")))
{
Id = null;
}
base.SetParameters(parameters);
}
Hope this helps...
Try this
@page "/"
@page "/{Id:string}"
<h1>Id = @Id</h1>
<p><NavLink href="/">Without Id</NavLink></p>
<p><NavLink href="/15">With Id = 15</NavLink></p>
@code{
[Parameter]
public string Id {get;set;}
}
I hope your problem is solved
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With