dotnet / AspNetCore.Docs

Documentation for ASP.NET Core
https://docs.microsoft.com/aspnet/core
Creative Commons Attribution 4.0 International
12.65k stars 25.29k forks source link

Blazor integration in ASP.NET MVC causes button and link actions to be executed twice #34110

Open KevinMartins84 opened 1 month ago

KevinMartins84 commented 1 month ago

Is there an existing issue for this?

Describe the bug

When integrating Blazor components into an existing ASP.NET MVC project following the official Blazor integration guide, I encountered an issue where actions like link and button clicks are executed twice. This happens when both regular MVC and Blazor components exist on the same page, and the _blazor.js script is included.

I observed this behavior using Chrome DevTools, where each click resulted in two network requests for the same action. This occurs even in a clean new MVC project with Blazor support added, following the tutorial.

Expected Behavior

Clicking on links or buttons should trigger the action only once, without interference from Blazor on regular MVC actions.

Steps To Reproduce

Create a new ASP.NET MVC project. Follow the official tutorial to add Blazor support. Include _blazor.js to enable Blazor components. (As described in the tutorial) Click on the menu item and observe the double execution of the action in the browser's network tab.

Git Repo: https://github.com/KevinMartins84/BugReportMVCWithBlazor

Exceptions (if any)

No response

.NET Version

dotnet --version

Anything else?

.NET SDK: Version: 8.0.403 Commit: c64aa40a71 Workload version: 8.0.400-manifests.e99c892e MSBuild version: 17.11.9+a69bbaaf5

Runtime Environment: OS Name: Windows OS Version: 10.0.22631 OS Platform: Windows RID: win-x64 Base Path: C:\Program Files\dotnet\sdk\8.0.403\

.NET workloads installed: Configured to use loose manifests when installing new manifests. [android] Installation Source: VS 17.11.35327.3 Manifest Version: 34.0.113/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.android\34.0.113\WorkloadManifest.json Install Type: FileBased

[maccatalyst] Installation Source: VS 17.11.35327.3 Manifest Version: 18.0.8303/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maccatalyst\18.0.8303\WorkloadManifest.json Install Type: FileBased

[ios] Installation Source: VS 17.11.35327.3 Manifest Version: 18.0.8303/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.ios\18.0.8303\WorkloadManifest.json Install Type: FileBased

[aspire] Installation Source: VS 17.11.35327.3 Manifest Version: 8.1.0/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.aspire\8.1.0\WorkloadManifest.json Install Type: FileBased

[maui-windows] Installation Source: VS 17.11.35327.3 Manifest Version: 8.0.82/8.0.100 Manifest Path: C:\Program Files\dotnet\sdk-manifests\8.0.100\microsoft.net.sdk.maui\8.0.82\WorkloadManifest.json Install Type: FileBased

Host: Version: 8.0.10 Architecture: x64 Commit: 81cabf2857

.NET SDKs installed: 8.0.403 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.35 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 7.0.20 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 8.0.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Other architectures found: x86 [C:\Program Files (x86)\dotnet] registered at [HKLM\SOFTWARE\dotnet\Setup\InstalledVersions\x86\InstallLocation]

Environment variables: Not set

global.json file: Not found

Learn more: https://aka.ms/dotnet/info

Download .NET: https://aka.ms/dotnet/download

mkArtakMSFT commented 1 week ago

Thanks for reporting this. This is indeed an issue with our guidance.

@guardrex for MVC integration we don't support blazor.web.js, it should be blazor.server.js instead. Can you please update the guidance to fix this.

KevinMartins84 commented 1 week ago

Thanks for reporting this. This is indeed an issue with our guidance.

@guardrex for MVC integration we don't support blazor.web.js, it should be blazor.server.js instead. Can you please update the guidance to fix this.

Hi Guardrex, when you change blazor.web.js to blazor.server.js, the blazor components are not (properly) loaded. (Or should make new issue for this)

guardrex commented 1 week ago

I'm a bit surprised that this went sideways because I tested the article's content and discussed the no-op App component requirement with Mackinnon. I'll adjust the article on https://github.com/dotnet/AspNetCore.Docs/issues/34112 and retest the scenarios.

@KevinMartins84 ... That's up to @mkArtakMSFT. I'm going to retest the guidance after I update it to use the Blazor Server script. I'll work on it tomorrow morning and report back here if I have the same outcome and can't fix it.

guardrex commented 1 week ago

@KevinMartins84 ... Not that it's going to matter because I think I can see where this is going, but can you explain this step further because thus far I'm not seeing double execution of an action (e.g., selecting the Privacy page/view in the menu) ...

Click on the menu item and observe the double execution of the action in the browser's network tab.

Can you make sure that you've disabled the Preserve log checkbox and show a screenshot/movie of your Network tab indicating the double-execution of an action?

Also ... minor point perhaps, but possibly important ... the guidance is to place the call to MapRazorComponents after the call to MapControllerRoute; but in your app, you have them reversed.

@mkArtakMSFT ... I specifically recall discussing the need for a no-op App component to make BWA/script API work. All of the guidance in the article is centered on using BWA API, including the BWA script. Did the lack of support become understood after I wrote the guidance, or was it known from conception at 8.0 that BWA/script API shouldn't work? ... and noting that I'm not detecting any faults here thus far.

If we're dropping the entire approach, what we'd be essentially doing is scrapping the entire article in favor of bringing back the 7.0 integration guidance, probably with minor updates to apply in 8.0/9.0, in ...

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerendering-and-integration?view=aspnetcore-7.0&pivots=server

Is that what we're doing?

KevinMartins84 commented 1 week ago

@KevinMartins84 ... Not that it's going to matter because I think I can see where this is going, but can you explain this step further because thus far I'm not seeing double execution of an action (e.g., selecting the Privacy page/view in the menu) ...

Click on the menu item and observe the double execution of the action in the browser's network tab.

Can you make sure that you've disabled the Preserve log checkbox and show a screenshot/movie of your Network tab indicating the double-execution of an action?

Also ... minor point perhaps, but possibly important ... the guidance is to place the call to MapRazorComponents after the call to MapControllerRoute; but in your app, you have them reversed.

@mkArtakMSFT ... I specifically recall discussing the need for a no-op App component to make BWA/script API work. All of the guidance in the article is centered on using BWA API, including the BWA script. Did the lack of support become understood after I wrote the guidance, or was it known from conception at 8.0 that BWA/script API shouldn't work? ... and noting that I'm not detecting any faults here thus far.

If we're dropping the entire approach, what we'd be essentially doing is scrapping the entire article in favor of bringing back the 7.0 integration guidance, probably with minor updates to apply in 8.0/9.0, in ...

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerendering-and-integration?view=aspnetcore-7.0&pivots=server

Is that what we're doing?

Image

guardrex commented 1 week ago

I can't repro that here.

MVC ...

Image

RP ...

Image

However, the direction that we're headed is to resurrect the 7.0 guidance for >=8.0 at ...

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/prerendering-and-integration?view=aspnetcore-7.0&pivots=server

... with updates for any 8.0/9.0 deltas. I'm just waiting for final confirmation that that's what we'll be doing.

guardrex commented 1 week ago

@mkArtakMSFT ... I'm reverted to the Blazor Server script on https://github.com/dotnet/AspNetCore.Docs/pull/34138. I've opened https://github.com/dotnet/AspNetCore.Docs/issues/34139 to check the guidance for 8.0/9.0-era updates and make 'hosting model' language changes for >=8.0. I hope to reach that early next week. I think that you can close here, and the docs issue will track the final updates.

guardrex commented 5 days ago

@mkArtakMSFT and @KevinMartins84 ... Done! 🎉 Updates completed between https://github.com/dotnet/AspNetCore.Docs/pull/34138 and https://github.com/dotnet/AspNetCore.Docs/pull/34156. I moved the hosted WASM pivot into its own article (<8.0) to reduce the distraction of that scenario.

The integration article for MVC/RP with the Blazor Server script is live at ...

https://learn.microsoft.com/en-us/aspnet/core/blazor/components/integration?view=aspnetcore-9.0

... and I've validated the guidance for both MVC and RP at 9.0.

@KevinMartins84 ... If you hit a 😈 with the guidance, use the Open a documentation issue link/feedback form at the bottom of the article.