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.36k stars 9.99k forks source link

Blazor [SupplyParameterFromQuery] not usable in OnInitialized() when navigating [dotnet 8.rc2] #51398

Closed ipax77 closed 12 months ago

ipax77 commented 1 year ago

Is there an existing issue for this?

Describe the bug

When adding multiple Query strings to a Blazor page they cannot be consumed.

    [SupplyParameterFromQuery]
    public string? Test1 { get; set; }

    [SupplyParameterFromQuery]
    public string? Test2 { get; set; }

At OnInitialized the parameters are null. At OnParametersSet they are set

When consuming the parameters in a SubComponent only one Parameter is set / consumable.

Reloading the page and navigating

    void Navigate()
    {
        NavigationManager.NavigateTo(NavigationManager.GetUriWithQueryParameters("counter",
            new Dictionary<string, object?>()
                    {
                    {"Test1", "Summer" },
                    {"Test2", "Winter" },
                    }
        ));
    }

produce different results, but never all parameters are sets.

Navigate result:

SupplyParameterFromQuery Test1: Summer
SupplyParameterFromQuery Test2: Winter
OnParametersSet Test1: Summer
OnParametersSet Test2: Winter

OnInitialized Test1:
OnInitialized Test2:

OnParametersSet TestComponent:
Test1: Summer
Test2: Winter

OnParametersSet snapshot
Test1: Summer
Test2:
OnInitialized snapshot
Test1:
Test2: Winter

OnInitialized TestComponent
Test1:
Test2:
OnParametersSet snapshot
Test1:
Test2:
OnInitialized snapshot
Test1:
Test2:

Reload result:

SupplyParameterFromQuery Test1: Summer
SupplyParameterFromQuery Test2: Winter
OnParametersSet Test1: Summer
OnParametersSet Test2: Winter
OnInitialized Test1: Summer
OnInitialized Test2: Winter

OnParametersSet TestComponent
Test1: Summer
Test2: Winter

OnParametersSet snapshot
Test1: Summer
Test2:
OnInitialized snapshot
Test1: Summer
Test2: Winter

OnInitialized TestComponent
Test1: Summer
Test2: Winter

OnParametersSet snapshot
Test1: Summer
Test2:
OnInitialized snapshot
Test1: Summer
Test2: Winter

Expected Behavior

The parameters should be consumable at/after page load (e.g. to use them for database requests)

Steps To Reproduce

SampleProject Click on 'Navigate' and reload the page with the parameters.

   [SupplyParameterFromQuery]
    public string? Test1 { get; set; }

    [SupplyParameterFromQuery]
    public string? Test2 { get; set; }

    TestRecord testRecord1 = new();
    TestRecord testRecord2 = new();

    protected override void OnParametersSet()
    {
        SetParameters1();
        base.OnParametersSet();
    }

    protected override void OnInitialized()
    {
        SetParameters2();
        base.OnInitialized();
    }

    void SetParameters1()
    {
        testRecord1.Test1 = Test1;
        testRecord1.Test2 = Test2;
    }

    void SetParameters2()
    {
        testRecord2.Test1 = Test1;
        testRecord2.Test2 = Test2;
    }

Exceptions (if any)

No response

.NET Version

8.0.100-rc.2.23502.2

Anything else?

Sample and test with Blazor wasm

kapryeong commented 1 year ago

It is also incorrect within the OnInitializedAsync method. (RC2) (ServerRenderMode) Weather.razor

<h1>Befor Task.Delay : @_beforName</h1>
<h1>After Task.Delay : @_afterName</h1>
<h1>@Name</h1>
@code {
    [SupplyParameterFromQuery]
    public string Name { get; set; }

    private string _beforName;
    private string _afterName;

    protected override async Task OnInitializedAsync()
    {
        _beforName = Name;        
        // Simulate asynchronous loading to demonstrate a loading indicator
        await Task.Delay(500);
        _afterName = Name;
    }
image
surayya-MS commented 1 year ago

I tried it out and got the same result - [SupplyParameterFromQuery] doesn't work in OnInitialized() when navigating but works when the page is refreshed

mkArtakMSFT commented 12 months ago

@ipax77 do you know if this is something you're experienced only in some rendering mode but not others?

ipax77 commented 12 months ago

@mkArtakMSFT the original test was on a Blazor wasm project. I added a blazor sample project with both render modes: SampleProject The results are inconsistent no matter from (Home (Server), Counter(Wasm)) or the to render mode. But it seems that in the blazor auto project either both parameters are set or both not. While on blazor wasm sometimes one or the other is set.

Parameters: Test1: Summer, Test2: Winter
OnParametersSetAsync: Test1: Summer, Test2: Winter
OnParametersSet: Test1: Summer, Test2: Winter
OnInitializedAsync: Test1: Summer, Test2: Winter
OnInitialized: Test1: Summer, Test2: Winter
Parameters: Test1: , Test2:
OnParametersSetAsync: Test1: , Test2:
OnParametersSet: Test1: , Test2:
OnInitializedAsync: Test1: , Test2:
OnInitialized: Test1: , Test2:
vindberg commented 12 months ago

Is there any way we can get this bug prioritized higher by the team or @SteveSandersonMS or @surayya-MS. It's a showstopper for our upgrade of watchpedia.com

akpatternica commented 12 months ago

so blazor in 8.0 will be completly unusable:(

surayya-MS commented 12 months ago

This has been addressed by this PR https://github.com/dotnet/aspnetcore/pull/51279

oliverw commented 11 months ago

This has been addressed by this PR #51279

Well, the fix does not work if you are using a non-interactive router in the server project.

oliverw commented 11 months ago

so blazor in 8.0 will be completly unusable:(

Maybe not unusable, but combined with the state management problem that is also not going to be addressed, it seriously degrades the experience.

seth-tc commented 10 months ago

Can confirm this issue exists in dotnet 8.0.100. Parameters provided via [SupplyParameterFromQuery] cannot be used in OnInitialized(Async) at all. They are NOT set on the component prior to OnInitialized being called. From the lifecycle docs here (https://learn.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-8.0#when-parameters-are-set-setparametersasync):

"OnInitialized and OnInitializedAsync are invoked when the component is initialized after having received its initial parameters in SetParametersAsync."

This was true in dotnet 7 (I am considered URL query string parameters to be "Initial parameters") but is not working for me in dotnet 8. I could not find any solution other than to manually parse out the parameters inside OnInitialized(Async) where needed.

The parameters are eventually set, but they are set in a second call to SetParametersAsync which occurs after OnInitialized(Async).

c4l3b commented 10 months ago

+1 confirming this is broken in 8.0.100. I'm using InteractiveWebAssemblyRenderMode with prerender:false. When navigating from another page, the query params are not set. When refreshing the page, they are set.

milkyjoe90 commented 9 months ago

I'm also experiencing this issue in 8.0 and 8.0.1, have reverted back to 7 in order to continue developing.

agilealtitude commented 9 months ago

Back to 7 I go, too. You would think this particular issue would have been tested and identified...

danm-de commented 7 months ago

@surayya-MS is there a way we can re-open this bug report? As of today, using .NET 8.0.200 with Blazor ServerApp we experience the same problem.

The properties marked with [SupplyParameterFromQuery] are not set correctly during OnInitialize / OnInitializeAsync.

Our users expect deep linking to work, so we use the OnInitializeAsync method to perform a database query with the desired filter conditions. The results have been incorrect since we switched to .NET8 because the values ​​in the query parameters are not correctly transferred to the marked properties.

Related: https://github.com/dotnet/aspnetcore/issues/53055

milkyjoe90 commented 7 months ago

It's been added to the 8.0.3 release, haven't seen any expected timelines sadly. I've stuck with 7 up to this point, once this is fixed I'll be able to upgrade to 8 (barring any other issues that testing hasn't found yet)

https://github.com/dotnet/aspnetcore/milestone/303?closed=1

danm-de commented 7 months ago

I can confirm that it works again with 8.0.3 🎆 👍

agilealtitude commented 7 months ago

Thanks for updating us :) I still don't understand how there was not more of an outcry from devs, like me, attempting to upgrade their Blazor project to .Net 8... This issue was a show stopper...

milkyjoe90 commented 7 months ago

I can also confirm this is working, the 8.0.3 release has allowed me to upgrade from dot net 7 up to 8 in production now.

JimGorman17 commented 6 months ago

Can confirm this issue exists in dotnet 8.0.100. Parameters provided via [SupplyParameterFromQuery] cannot be used in OnInitialized(Async) at all. They are NOT set on the component prior to OnInitialized being called. From the lifecycle docs here (https://learn.microsoft.com/en-us/aspnet/core/blazor/components/lifecycle?view=aspnetcore-8.0#when-parameters-are-set-setparametersasync):

"OnInitialized and OnInitializedAsync are invoked when the component is initialized after having received its initial parameters in SetParametersAsync."

This was true in dotnet 7 (I am considered URL query string parameters to be "Initial parameters") but is not working for me in dotnet 8. I could not find any solution other than to manually parse out the parameters inside OnInitialized(Async) where needed.

The parameters are eventually set, but they are set in a second call to SetParametersAsync which occurs after OnInitialized(Async).

Correct. Why is this issue closed and marked as fixed? Still broken with 8.0.3.

milkyjoe90 commented 6 months ago

This issue was confirmed fixed for me in the 8.0.3 release, and in limited testing, appears not to have regressed and still work fine for me in 8.0.4. I’ll do more testing locally of 8.0.4 when I’m back at my desk properly tomorrow

ozersenol commented 4 months ago

When Navigating from page A to page B and setting multiple parameters with SupplyParameterFromQuery it works. But if you move on Navigating page B to page C and use different SupplyParameterFromQuery parameters, the parameters comes null. and also parameters set on B are still cached with the same Name property. I tried it on production with 8.0.3

ArdorDeosis commented 3 months ago

8.0.3, Blazor Interactive Server I navigate from one page to another, Cookie auth kicks in and redirects me to the login page with query parameter "returnUrl".

setup:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
  .AddCookie(options =>
  {
    options.Cookie.HttpOnly = false;
    options.LoginPath = "/login";
    options.ReturnUrlParameter = "returnUrl";
  });

in the component:

[SupplyParameterFromQuery]
private string ReturnUrl { get; set; } = "/";

ReturnUrl is null, when I actually want to navigate to it after doing the authentication and setting the cookies. I don't know how exactly that redirect works. What I could observe was: