Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CascadingParameter set in MainLayout.razor doesn't work as expected in .NET 8 #51955

Closed
1 task done
ruikaifeng opened this issue Nov 9, 2023 · 3 comments
Closed
1 task done
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: By Design Resolved because the behavior in this issue is the intended design. Status: Resolved

Comments

@ruikaifeng
Copy link

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

The the cascading parameters work properly only during prerender:
11 9 1

I found a workaround that set rendermode to InteractiveServer gobally in app.razor

<Routes @rendermode="RenderMode.InteractiveServer" />

11 9 2

Expected Behavior

The the cascading parameters work properly without setting rendermode to InteractiveServer gobally

Steps To Reproduce

codes in Razor Components:

@attribute [RenderModeInteractiveServer]

<h1>Themed Counter</h1>
<p>Current count: @currentCount</p>
<p>
    <button class="btn @(ThemeInfo is not null ? ThemeInfo.ButtonClass : string.Empty)"
            @onclick="IncrementCount">
        Increment Counter (Themed)
    </button>
</p>

@code {
    private int currentCount = 0;       

    [CascadingParameter]
    // this themeinfo is only cascaded properly during prerender
    protected ThemeInfo? ThemeInfo { get; set; } 

    private void IncrementCount()
    {
        currentCount++;
    }
    protected override void OnInitialized()
    {
        base.OnInitialized();
    }
}

mainlayout:

@inherits LayoutComponentBase


<div class="page">
    <div class="sidebar">
        <NavMenu />
    </div>

    <main>
        <div class="top-row px-4">
            <a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
        </div>

        <CascadingValue Value="@theme" >
            <article class="content px-4">
                @Body
            </article>
        </CascadingValue>
    </main>
</div>

@code {
    private ThemeInfo theme = new ThemeInfo { ButtonClass = "btn-success" };
}

Exceptions (if any)

No response

.NET Version

8.0.100-rc.2.23502.2

Anything else?

No response

@dotnet-issue-labeler dotnet-issue-labeler bot added the area-blazor Includes: Blazor, Razor Components label Nov 9, 2023
@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Nov 9, 2023

Cascading parameters don't cross rendermode boundaries. This is because:

  1. It would break most existing apps if the framework tried to serialize them, because in general one should not expect their values to be serializable.
  2. Top-level cascading parameters are often used as a DI alternative, and so you should expect to have different data on different hosting platforms. For example, in static SSR there's a cascading HttpContext. It would not make sense to serialize that out and rehydrate it for interactive rendering, since at that time there's either a different HTTP context or even no HTTP context at all.

Of course, this will be covered in the .NET 8 docs when they are published.

As a solution, you should use builder.Services.AddCascadingParameter (including in your .Client project if you're also using WebAssembly) to register cascading values, so your app supplies a value for each hosting platform. Then a value will always be available, and it's your responsibility as the app developer to determine that value for each hosting platform.

If you actually need to transfer dynamically-determined data from static SSR into interactive components, the PersistentComponentState API exists for that purpose: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.persistentcomponentstate?view=aspnetcore-7.0. This does work by serializing out whatever state you register so that it becomes available to interactive components.

@SteveSandersonMS SteveSandersonMS added the ✔️ Resolution: By Design Resolved because the behavior in this issue is the intended design. label Nov 9, 2023
@ghost ghost added the Status: Resolved label Nov 9, 2023
@guardrex
Copy link
Contributor

guardrex commented Nov 9, 2023

Just to let you know, @ruikaifeng, docs will cover this after dotnet/AspNetCore.Docs#30958 merges, which will be later this afternoon.

@ghost
Copy link

ghost commented Nov 10, 2023

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.

@ghost ghost closed this as completed Nov 10, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Feb 7, 2024
This issue was closed.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components ✔️ Resolution: By Design Resolved because the behavior in this issue is the intended design. Status: Resolved
Projects
None yet
Development

No branches or pull requests

3 participants