Description
Summary
Under the right conditions, components that exist in the subtree of a @page
component and have one or more [SupplyParameterFromQuery]
properties might receive query parameter values for the next URL being navigated to.
Context
I originally found this bug when updating the Blazor E2E test app in #57557. I added a [SupplyParameterFromQuery]
property to the root component, and this broke a test verifying that you can navigate between two @page
components, both with [SupplyParameterFromQuery]
properties for the same query value name, but expecting a different query value type.
Details
There's an assumption in the implementation of SupplyParameterFromQueryValueProvider
that its OnLocationChanged
event callback will get executed after Router.OnLocationChanged
when a navigation occurs. This assumption is not a guarantee. Both callbacks are invoked from the NavigationManager.LocationChanged
event, so the order of execution of each callback depends on their respective subscription order.
The SupplyParameterFromQueryValueProvider
subscribes to NavigationManager.LocationChanged
as soon as a component with a [SupplyParameterFromQuery]
property gets initialized, and the Router
subscribes upon its own initialization. In the common case, the first [SupplyParameterFromQuery]
component will be deeper in the component hierarchy than the Router
, so the rendering order between the two components causes the event subscription order to match what SupplyParameterFromQueryValueProvider
expects.
However, if a root component contains a [SupplyParameterFromQuery]
property, then the subscription order gets inverted, breaking the assumption made by SupplyParameterFromQueryValueProvider
.
This is bad because it means that, before getting disposed, a page and its subtree could receive query parameter values for the URL being navigated to. It's effectively the problem opposite to the one fixed by #53443.