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

duplicated ProjectReferences to razor class libraries lead to builds failing because of FilterStaticWebAssetEndpoints #58354

Open AdmiralSnyder opened 1 week ago

AdmiralSnyder commented 1 week ago

Is there an existing issue for this?

Describe the bug

when upgrading my blazor website from .net8 to .net9 rc2, i moved a couple of shared ProjectReferences to razor class library projects into a Directory.build.props file, but forgot to delete those in all projects. turns out, duplicated nodes are not a good thing, because the blazor tooling(i suspect) doesn't make them unique, properly.

this can be easily reproduced by just duplicating a node in the .csproj file. if that points to something not affected by the blazor tooling, it won't error. if it does, it will. (maybe it's necessary for that razor class library to actually contain .razor.css files, but the binlog doesn't suggest that)

Expected Behavior

either an error complaining about the duplicated ProjectReference in the .csproj or proper deduplication so it doesn't fail in the first place

Steps To Reproduce

see this project: https://github.com/AdmiralSnyder/ErrorRepros/tree/master/20241010_duplicated_projectreferences

repro workflow:

Exceptions (if any)

C:\Program Files\dotnet\sdk\9.0.100-rc.1.24452.12\Sdks\Microsoft.NET.Sdk.StaticWebAssets\targets\Microsoft.NET.Sdk.StaticWebAssets.ScopedCss.targets(397,3): error MSB4018: The "FilterStaticWebAssetEndpoints" task failed unexpectedly. System.ArgumentException: An item with the same key has already been added. Key: D:\source\GVT\GVTShowcase\BlazorComponents\obj\Debug\net9.0\scopedcss\projectbundle\BlazorComponents.bundle.scp.css at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value) at System.Linq.Enumerable.SpanToDictionary[TSource,TKey,TElement](ReadOnlySpan1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func2 elementSelector, IEqualityComparer1 comparer) at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable1 source, Func2 keySelector, Func`2 elementSelector) at Microsoft.AspNetCore.StaticWebAssets.Tasks.FilterStaticWebAssetEndpoints.Execute() at Microsoft.Build.BackEnd.TaskExecutionHost.Execute() at Microsoft.Build.BackEnd.TaskBuilder.ExecuteInstantiatedTask(TaskExecutionHost taskExecutionHost, TaskLoggingContext taskLoggingContext, TaskHost taskHost, ItemBucket bucket, TaskExecutionMode howToExecuteTask) [D:\source\GVT\GVTShowcase\Contents\GVT\Contents.GVT\Contents.GVT.csproj]

.NET Version

9.0.100-rc.1.24452.12

Anything else?

If you want, i can add a binlog file to the repro repo. Since this is circumvented easily, i can totally get if this issue isn't prioritized. a better error message would really be nice, though. Because finding it required @davidwengier having a look at that binlog.

Thanks for looking into this ❤

here's the dotnet --info output:

dotnet --info .NET SDK: Version: 9.0.100-rc.1.24452.12 Commit: 81a714c6d3 Workload version: 9.0.100-manifests.67cd1eb6 MSBuild version: 17.12.0-preview-24422-09+d17ec720d

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

.NET workloads installed: Configured to use loose manifests when installing new manifests. [ios] Installation Source: VS 17.12.35323.107 Manifest Version: 17.5.9270-net9-rc1/9.0.100-rc.1 Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100-rc.1\microsoft.net.sdk.ios\17.5.9270-net9-rc1\WorkloadManifest.json Install Type: Msi

[android] Installation Source: VS 17.12.35323.107 Manifest Version: 35.0.0-rc.1.80/9.0.100-rc.1 Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100-rc.1\microsoft.net.sdk.android\35.0.0-rc.1.80\WorkloadManifest.json Install Type: Msi

[maui-windows] Installation Source: VS 17.12.35323.107 Manifest Version: 9.0.0-rc.1.24453.9/9.0.100-rc.1 Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100-rc.1\microsoft.net.sdk.maui\9.0.0-rc.1.24453.9\WorkloadManifest.json Install Type: Msi

[maccatalyst] Installation Source: VS 17.12.35323.107 Manifest Version: 17.5.9270-net9-rc1/9.0.100-rc.1 Manifest Path: C:\Program Files\dotnet\sdk-manifests\9.0.100-rc.1\microsoft.net.sdk.maccatalyst\17.5.9270-net9-rc1\WorkloadManifest.json Install Type: Msi

Host: Version: 9.0.0-rc.1.24431.7 Architecture: x64 Commit: static

.NET SDKs installed: 6.0.425 [C:\Program Files\dotnet\sdk] 7.0.410 [C:\Program Files\dotnet\sdk] 8.0.108 [C:\Program Files\dotnet\sdk] 9.0.100-rc.1.24452.12 [C:\Program Files\dotnet\sdk]

.NET runtimes installed: Microsoft.AspNetCore.App 6.0.33 [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.8 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 9.0.0-rc.1.24452.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 6.0.33 [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.8 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 9.0.0-rc.1.24431.7 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 6.0.33 [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.8 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 9.0.0-rc.1.24452.1 [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

javiercn commented 1 week ago

@AdmiralSnyder thanks for contacting us.

It's very likely that this problem already existed in previous versions, and you are now seeing it manifest in a different way with the newer SDK. The cause is likely that there are duplicate assets in the pipeline which will very likely cause an issue at the time we generate the manifest.

The solution as you mentioned is to avoid having the duplicate reference in the project file. I'm surprised that the project system doesn't de-dupe these, as we don't consume the raw ProjectReference and only the results after they have been processed.

I think a fix here would likely involve improving the logic for ProjectReference to either error out or de-duplicate the references, we shouldn't be including logic to de-dupe them ourselves.

I'm going to move this issue to the backlog so that we can follow up with other folks on addressing this in the future.