Skip to content

Better dev. experience when AddServerRenderMode or AddWebAssemblyRenderMode is missing #49312

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

Closed
danroth27 opened this issue Jul 10, 2023 · 14 comments
Assignees
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. feature-full-stack-web-ui Full stack web UI with Blazor
Milestone

Comments

@danroth27
Copy link
Member

I'm trying to upgrade a Blazor Server app to .NET 8 using the new full stack web UI model. I've setup the Blazor Router component to render using the server interactive render mode, but the rendered pages (like the counter) don't render interactively.

Repro steps:

Expected result: The counter works
Actual result: The counter doesn't increment when clicked

@ghost ghost added the area-blazor Includes: Blazor, Razor Components label Jul 10, 2023
@danroth27
Copy link
Member Author

@SteveSandersonMS Is this really the same issue as #49303?

@SteveSandersonMS
Copy link
Member

@danroth27 The issue is that the MapRazorComponents middleware doesn't realise you're using Server rendermode (because it only sees [RenderModeServer], not @rendermode="Server") and hence doesn't enable the endpoints for server. Two possible workarounds:

  1. Tell it explicitly. In Program.cs, update MapRazorComponents to add AddServerRenderMode. That is, line 29 becomes app.MapRazorComponents<Host>().AddServerRenderMode();
  2. Or, change App.razor to contain @attribute [RenderModeServer] instead of using callsite rendermode for that component.

@javiercn Now we support callsite rendermodes we can't rely on statically detecting rendermodes. Do you have a preference on how to handle this? I'd recommend we change the source generator not to try doing static detection since that can't be reliable, and instead register the endpoints:

  • By default based on which DI services were configured. For example, if you have AddServerComponents then we should behave as if you also have AddServerRenderMode by default.
  • (Optional) ... and if people really want to override this for different branches in the middleware pipeline, let them. For example we could allow something like app.MapRazorComponents<Host>().ClearRenderModes().AddServerRenderMode(); so the DI services can be ignored. This will be a very niche edge case though so I think it would be fine if we didn't have this initially in NET 8.

What do you think?

@mkArtakMSFT mkArtakMSFT added bug This issue describes a behavior which is not expected - a bug. feature-full-stack-web-ui Full stack web UI with Blazor labels Jul 12, 2023
@mkArtakMSFT mkArtakMSFT added this to the 8.0-rc1 milestone Jul 12, 2023
@AmarjeetBanwait
Copy link

Well adding .AddServerRenderMode(); and removing @attribute [RenderModeServer] from Counter.razor makes routing intractive. But button on Counter.razor stops working.

FetchData.razor page is also intractively loading but Removing @attribute [StreamRendering(true)] Loading... section doesn't show up page doesn't change content untill OnInitializedAsync finishes.

Adding @attribute [RenderModeServer] in counter.razor breaks intractive routing but now counter button works and app fallbacks to full page refresh.

Also ToggleNavMenu button doesn't work without adding @attribute [RenderModeServer] in NavMenu.razor but again this will break intractive routing.

@Dulatr
Copy link

Dulatr commented Jul 31, 2023

Commented in a different issue that was closed out for updates coming in Preview 7, but to @AmarjeetBanwait's comment I'm not able to get interactivity working any combination of those. Is there a current working sample I can view that demonstrates the interactivity in Preview 6?

@danroth27
Copy link
Member Author

@Dulatr Did you try creating a Blazor Web App using the new template and selecting the "Use interactive server components" option? That should enable interactivity for the Counter component. If you want to see how to enable interactivity for the entire app using Blazor Server see https://github.com/danroth27/Net8BlazorServer.

@Dulatr
Copy link

Dulatr commented Jul 31, 2023

@danroth27 Thank you for that. Your repo provided solved my problem exactly. A combination of the <RazorLangVersion>8.0</RazorLangVersion> workaround, the migration of the _Host.cshtml to the Host.razor, and the differences in the program file fixed it for me. Enabling interactivity for the entire app suits the need of our test project. I feel a bit silly missing a lot of that in the original posting.

@SteveSandersonMS SteveSandersonMS removed this from the .NET 9 Planning milestone Aug 14, 2023
@SteveSandersonMS SteveSandersonMS removed the bug This issue describes a behavior which is not expected - a bug. label Aug 14, 2023
@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Aug 14, 2023

@mkArtakMSFT @javiercn @danroth27

I'm pinging everyone again (and changing labels so this comes up in triage) because it seems we still don't have any plan to address this. I did raise this repeatedly during API review but didn't get any traction on us solving it.

Today one of the team's engineers burned quite a bit of time not understanding why interactive rendering wasn't working, and in the end it was because of not having AddServerRenderMode. The problem is very hard for developers to understand because the error message makes no sense (startup fails with a 404 from /blazor/_initializers, which doesn't even remotely hint at the underlying cause).

I think the options are:

  • Hacky fix: Change the JS-side code so that if /blazor/_initializers returns a 404, we show an error message like "The server isn't handling endpoints for this interactive render mode. Make sure your call to MapRazorComponents is followed by calls to AddServerRenderMode or AddWebAssemblyRenderMode as needed".
    • I regard this as hacky because it's just an arbitrary fact that the error is first hit by _initializers. If we change the startup process in the future, the error might come from somewhere else.
  • Better fix: Change MapRazorComponents so that it implicitly calls AddServerRenderMode and/or AddWebAssemblyRenderMode based on which DI services are registered.
    • For the edge case where someone wants not to enable the endpoints matching their DI config (which really is an edge case), we could have an overload like MapRazorComponents(addInteractiveEndpoints: false) then those people would have to call AddServerRenderMode/AddWebAssemblyRenderMode manually.

@surayya-MS surayya-MS added this to the 8.0-rc2 milestone Aug 15, 2023
@jinzhao1127
Copy link

jinzhao1127 commented Aug 17, 2023

I can repro this issue on the latest .NET8.0 RC1 build with following steps:

  1. File > New Project > Select "Blazor Web App " template > Next, Give a name > Next > select ".NET 8.0" > Checking Use interactive server components and uncheck Include sample pages > Create

  2. Open Components/Pages/Home.razor, add following code. and place a breakpoint at var foo = "bar"; line.

    <button @onclick=DoSomething>Do Something</button>
    
    @code {
      public void DoSomething()
      {
        var foo = "bar";
      }
    }
  3. Run the project (F5), after the webpage load successfully and then click the Do Something button.

Result: Do Something button no interactive.

In my Program.cs file contain the app.MapRazorComponents<App>().AddServerRenderMode(); by default.

My Repro solution here https://github.com/jinzhao1127/BlazorWebServerApp.git

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Aug 17, 2023

@jinzhao1127 You have to mark component subtrees as interactive if you want them to be. For example, at the top of Home.razor, add:

@attribute [RenderModeServer]

In the final version of .NET 8, this will be changed to @rendermode Server.

@jinzhao1127
Copy link

@SteveSandersonMS Thanks, After adding @attribute [RenderModeServer] in Home.razor, it works well.

@EmilyFeng97
Copy link

When I follow the same steps as Jin's comment in Blazor Web App for WASM project, the "Do Something" button is not interactive. So I try to add @attribute [RenderModeWebAssembly] at the top of Home.razor and I get some errors in the browser console.
@SteveSandersonMS Please help to confirm if this is the expected result? If not, is there some workaround?
image

@lanedirt
Copy link

Just to confirm what @EmilyFeng97 reports: I tried the exact same yesterday with .NET 8 preview 7, and got the same error. Just didn't found the time to report the bug yet. But +1 from me that it is reproducible, would love to know if there is a workaround.

@SteveSandersonMS
Copy link
Member

@EmilyFeng97 Enabling WebAssembly is different from enabling Server. For WebAssembly you have to have a separate, WebAssembly-specific project, since it has to compile in a different way.

Please see the project templates in RC1 which have options for enabling Server or WebAssembly interactivity (or both).

@mkArtakMSFT mkArtakMSFT added the bug This issue describes a behavior which is not expected - a bug. label Aug 21, 2023
@mkArtakMSFT mkArtakMSFT changed the title Pages in Blazor app are not interactive even though the Router is rendered with an interactive render mode Better dev. experience when AddServerRenderMode or AddWebAssemblyRenderMode is missing Aug 21, 2023
@SteveSandersonMS
Copy link
Member

Done in #50311

@ghost ghost locked as resolved and limited conversation to collaborators Sep 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components bug This issue describes a behavior which is not expected - a bug. feature-full-stack-web-ui Full stack web UI with Blazor
Projects
None yet
Development

No branches or pull requests

9 participants