Luis Abreu
Luis Abreu

Reputation: 4560

Blazor WASM: how to find out which parameter changed during parameterset

I'm facing a strange issue while overriding the OnParameterSetAsync on a complex blazor wasm app. The page has several parameters which get their value from the querystring:


[SupplyParameterFromQuery(Name = "i")]
[Parameter]
public string? Info{ get; set; }

The issue we're having is that the parameter isn't being set when the user navigates back to the page, i.e., when the user goes back in history (ex.: browser's back button) and navigates to page1?i=something, the OnParameterSetAsync method is called several times, but during the first call, the page's properties haven't been set from the querystring. I've added some logging to the OnParameterSetAsync and here's what I'm seeing:

dotnet.native.8.0.1.kh3byfzycl.js:8 1/23/2024 10:51:07 AM -> https://localhost:5001/equipamentos?i=something ---> 
dotnet.native.8.0.1.kh3byfzycl.js:8 1/23/2024 10:51:07 AM -> https://localhost:5001/equipamentos?i=something --->something

As you can see, the method OnParameterSetAsync gets called twice during the reloading of the page. During the first call, and event though the URI is correct (recovered from the NavigationManager that is injected into the page) the Page´s Info property is not set, but during the second call, the property has been correctly initialized from the querystring parameter.

I've also captured the stack trace of both method calls. This is the one I've got when the page's properties haven't been set from the querystring yet:

dotnet.native.8.0.1.kh3byfzycl.js:8    at Grm.Assistencias.Web.Pages.Secured.Equipamentos.Equipamentos.OnParametersSetAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[<OnParametersSetAsync>d__61](<OnParametersSetAsync>d__61& stateMachine)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Grm.Assistencias.Web.Pages.Secured.Equipamentos.Equipamentos.OnParametersSetAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[<RunInitAndSetParametersAsync>d__21](<RunInitAndSetParametersAsync>d__21& stateMachine)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.ComponentBase.SetParametersAsync(ParameterView parameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Rendering.ComponentState.SetDirectParameters(ParameterView parameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewComponentFrame(DiffContext& diffContext, Int32 frameIndex)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InitializeNewSubtree(DiffContext& diffContext, Int32 frameIndex)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.InsertNewFrame(DiffContext& diffContext, Int32 newFrameIndex)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForFramesWithSameSequence(DiffContext& diffContext, Int32 oldFrameIndex, Int32 newFrameIndex)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.AppendDiffEntriesForRange(DiffContext& diffContext, Int32 oldStartIndex, Int32 oldEndIndexExcl, Int32 newStartIndex, Int32 newEndIndexExcl)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.RenderTreeDiffBuilder.ComputeDiff(Renderer renderer, RenderBatchBuilder batchBuilder, Int32 componentId, ArrayRange`1 oldTree, ArrayRange`1 newTree)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Rendering.ComponentState.RenderIntoBatch(RenderBatchBuilder batchBuilder, RenderFragment renderFragment, Exception& renderFragmentException)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.Renderer.RenderInExistingBatch(RenderQueueEntry renderQueueEntry)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessRenderQueue()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.Renderer.ProcessPendingRender()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer.ProcessPendingRender()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderTree.Renderer.AddToRenderQueue(Int32 componentId, RenderFragment renderFragment)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.RenderHandle.Render(RenderFragment renderFragment)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Routing.Router.Refresh(Boolean isNavigationIntercepted)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Routing.Router.RunOnNavigateAsync(String path, Boolean isNavigationIntercepted)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[<RunOnNavigateAsync>d__76](<RunOnNavigateAsync>d__76& stateMachine)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Routing.Router.RunOnNavigateAsync(String path, Boolean isNavigationIntercepted)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Routing.Router.OnLocationChanged(Object sender, LocationChangedEventArgs args)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.NavigationManager.NotifyLocationChanged(Boolean isInterceptedLink)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.WebAssemblyNavigationManager.SetLocation(String uri, String state, Boolean isInterceptedLink)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Infrastructure.JSInteropMethods.NotifyLocationChanged(String uri, String state, Boolean isInterceptedLink)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Object.InvokeStub_JSInteropMethods.NotifyLocationChanged(Object , Span`1 )
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime jsRuntime, DotNetInvocationInfo& callInfo, IDotNetObjectReference objectReference, String argsJson)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo invocationInfo, String argsJson)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime.<>c.<BeginInvokeDotNet>b__12_0(ValueTuple`2 state)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyCallQueue.Schedule[ValueTuple`2](ValueTuple`2 state, Action`1 callback)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime.BeginInvokeDotNet(String callId, String assemblyNameOrDotNetObjectId, String methodIdentifier, String argsJson)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime.__Wrapper_BeginInvokeDotNet_1056649169(JSMarshalerArgument* __arguments_buffer)

And here's the one I got from the second call (when the page's properties have been initialized from the querystring):

dotnet.native.8.0.1.kh3byfzycl.js:8    at Grm.Assistencias.Web.Pages.Secured.Equipamentos.Equipamentos.OnParametersSetAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[<OnParametersSetAsync>d__61](<OnParametersSetAsync>d__61& stateMachine)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Grm.Assistencias.Web.Pages.Secured.Equipamentos.Equipamentos.OnParametersSetAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.ComponentBase.CallOnParametersSetAsync()
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.ComponentBase.SetParametersAsync(ParameterView parameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Rendering.ComponentState.SupplyCombinedParameters(ParameterView directAndCascadingParameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.Rendering.ComponentState.NotifyCascadingValueChanged(ParameterViewLifetime& lifetime)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.SupplyParameterFromQueryProviderServiceCollectionExtensions.SupplyValueFromQueryValueProvider.OnLocationChanged(Object sender, LocationChangedEventArgs args)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.NavigationManager.NotifyLocationChanged(Boolean isInterceptedLink)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.WebAssemblyNavigationManager.SetLocation(String uri, String state, Boolean isInterceptedLink)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Infrastructure.JSInteropMethods.NotifyLocationChanged(String uri, String state, Boolean isInterceptedLink)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Object.InvokeStub_JSInteropMethods.NotifyLocationChanged(Object , Span`1 )
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Reflection.MethodBaseInvoker.InvokeWithFewArgs(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
dotnet.native.8.0.1.kh3byfzycl.js:8    at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.InvokeSynchronously(JSRuntime jsRuntime, DotNetInvocationInfo& callInfo, IDotNetObjectReference objectReference, String argsJson)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.JSInterop.Infrastructure.DotNetDispatcher.BeginInvokeDotNet(JSRuntime jsRuntime, DotNetInvocationInfo invocationInfo, String argsJson)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime.<>c.<BeginInvokeDotNet>b__12_0(ValueTuple`2 state)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Hosting.WebAssemblyCallQueue.Schedule[ValueTuple`2](ValueTuple`2 state, Action`1 callback)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime.BeginInvokeDotNet(String callId, String assemblyNameOrDotNetObjectId, String methodIdentifier, String argsJson)
dotnet.native.8.0.1.kh3byfzycl.js:8    at Microsoft.AspNetCore.Components.WebAssembly.Services.DefaultWebAssemblyJSRuntime.__Wrapper_BeginInvokeDotNet_1056649169(JSMarshalerArgument* __arguments_buffer)
dotnet.native.8.0.1.kh3byfzycl.js:8 

Both calls are almost sequential, but since we're only handling the 1st call, this means that the page doesn't work as expected.

All the parameters explicitly defined by the page get their values from the querystring, so I'm not sure on what's happening to fire the OnParameterSetAstnc method (probably something has changes, but what?). The app was built from the Blazor Wasm standalone template and it uses AD authentication (so, the App component is using the CascadingAuthenticationState and the Router component which, if I'm not mistaken, propagate several properties (though this page doesn't explicitly consume any of those parameters through properties).

EDIT: forgot to mention that I've overriden the SetParametersAsync method on that page and can confirm that the only parameters passed on the ParameterView object that the method received are the ones that are bound to the page's properties through querystring parameters. That method also gets called twice and during the first call, none of the parameters have been set. By the time SetParameterAsync gets called a second time, the parameters have been initialized to the values passed on the querystring.

Any ideas on what might be happening here?

Upvotes: 0

Views: 244

Answers (1)

Luis Abreu
Luis Abreu

Reputation: 4560

After spending several hours trying to reproduce and isolate the bug, I've finally tracked it down to something which has been reported more than one year ago and still isn't fixed:

https://github.com/dotnet/aspnetcore/issues/44781

Upvotes: 0

Related Questions