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

VS inserts unwanted csproj items when copy/pasting .razor.css files #24790

Closed
SteveSandersonMS opened this issue Aug 11, 2020 · 16 comments
Closed
Assignees
Labels
area-blazor Includes: Blazor, Razor Components area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates External This is an issue in a component not contained in this repository. It is open for tracking purposes.
Milestone

Comments

@SteveSandersonMS
Copy link
Member

I have a project with some .razor.css files. When copy-pasting them (e.g., to duplicate the file with a new name), it adds unwanted junk to the csproj. Currently I have got the following, which breaks compilation and has to be removed manually:

  <ItemGroup>
    <None Remove="Pages\AllGrid.razor.css" />
    <None Remove="Pages\Grid - Copy - Copy.razor.css" />
    <None Remove="Pages\Grid - Copy.razor.css" />
    <None Remove="Pages\Grid.razor.css" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Pages\AllGrid.razor.css" />
    <Content Include="Pages\Grid - Copy - Copy.razor.css">
      <DependentUpon>Grid - Copy.razor.css</DependentUpon>
    </Content>
    <Content Include="Pages\Grid - Copy.razor.css">
      <DependentUpon>Grid.razor.css</DependentUpon>
    </Content>
    <Content Include="Pages\Grid.razor.css" />
  </ItemGroup>
@SteveSandersonMS SteveSandersonMS added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates area-blazor Includes: Blazor, Razor Components labels Aug 11, 2020
@pranavkm pranavkm added this to the 5.0.0-rc1 milestone Aug 11, 2020
@pranavkm
Copy link
Contributor

@NTaylorMullen \ @ajaybhargavb do you happen to know how this needs to be resolved?

@NTaylorMullen
Copy link
Contributor

@NTaylorMullen \ @ajaybhargavb do you happen to know how this needs to be resolved?

Oh goodness, no idea. We'll have to query others who have more context.

@davkean is this on the CPS front that handles this?

@davkean
Copy link
Member

davkean commented Aug 11, 2020

To avoid unexpected behavior, VS is trying to avoid including a file multiple times in both None/Content. Looks like the SDK has them included under globs in None.

What is the end result you are expecting? And what Item do you expect these css files to be under?

@SteveSandersonMS
Copy link
Member Author

SteveSandersonMS commented Aug 12, 2020

We expect the csproj not to include any explicit references to these files individually. @javiercn, do you have an answer for "what Item do you expect these css files to be under?"? I would have thought <Content> but Javier is the expert on this bit of the Razor SDK.

The desired UX is the same as when copy/pasting a .cs file in VS's Solution Explorer - it doesn't add anything to your csproj.

Do you think the problem is in the SDK with how it matches them with globs? Is there a recommended pattern we should follow for populating itemgroups in a different way to avoid having VS think it should update the csproj when copy/pasting items?

@davkean
Copy link
Member

davkean commented Aug 12, 2020

It's hard to tell, can you paste the entire project? How did you add first css file originally?

VS has a few rules:

  1. It tries to avoid including a file more than once; that is the <None Remove="" />
  2. It maintains the "item type" when you copy and paste, that will be the reason the "- Copy" files have an item type of <Content/>

I can't tell why the first <Content /> item was added. Our defaults have CSS as "Content" which probably disagrees with the SDK you are using.

@SteveSandersonMS
Copy link
Member Author

Sure, I'm using .NET 5.0.100-rc.1.20407.13 and VS 16.8.0 Preview 1.0, and here's my entire csproj before adding any .razor.css files:

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <AnalysisLevel>4</AnalysisLevel>
  </PropertyGroup>

</Project>

FYI this project was created via dotnet new blazorserver using the 5.0.100-rc.1.20407.13 SDK.

Weirdly I can no longer repro this problem at all. I've tried creating .razor.css files in a bunch of places and copy/pasting them, renaming them, and today it's not adding anything to the csproj. It's hard to think of what I was doing wrong before that should legitimately have resulted in that content being added to my csproj, but without being able to repro it I can't really make any more concrete statement.

@davkean @javiercn Unless either of you have ideas for what might repro this, I propose just to close it. If others encounter the issue perhaps they will discover repro steps.

@mkArtakMSFT
Copy link
Member

mkArtakMSFT commented Aug 30, 2020

@SteveSandersonMS should this be closed now?

@javiercn
Copy link
Member

No, we are investigating this.

@SteveSandersonMS
Copy link
Member Author

When resolving this, please check if #25841 is also resolved as I think it's the same underlying cause.

@zHaytam
Copy link
Contributor

zHaytam commented Sep 17, 2020

Not sure if this will help but, the issue doesn't only occur when copy/pasting css files, but also when creating them.
I just created a new project using .net 5 rc1, and I'm not sure when exactly the issue started, but right now whenever I create a new css file that is supposed to become scoped, the csproj file gets updated with content such as:

<ItemGroup>
    <Content Remove="Components\DiagramContainer.razor" />
  </ItemGroup>

  <ItemGroup>
    <None Remove="Components\DiagramContainer.razor.css" />
  </ItemGroup>

  <ItemGroup>
    <Watch Remove="Components\DiagramContainer.razor" />
    <Watch Remove="Components\DiagramContainer.razor.css" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Components\DiagramContainer.razor.css" />
  </ItemGroup>

  <ItemGroup>
    <None Include="Components\DiagramContainer.razor" />
  </ItemGroup>

I'm still unsure how to reproduce this at 100%.

@SteveSandersonMS
Copy link
Member Author

SteveSandersonMS commented Sep 24, 2020

OK, I looked into this and found it has nothing to do with Blazor or the Razor SDK. I can repro the same problem with plain old .cs files in a default new Console Application project. So I think it's purely a VS issue.

Repro steps, based on VS 16.8.0 Preview 3.1:

  1. Create a new .NET Core C# Console Application project
  2. In Solution Explorer, select Program.cs
  3. Press Ctrl+C then Ctrl+V. This will create a new file called Program - Copy.cs
  4. Select Program - Copy.cs and right-click then choose Rename
  5. Enter the new name Program.cs.blah (or any other .cs.* extension) and press enter
  6. Look at your .csproj (after File -> Save All or doing a build gesture)

Expected: .csproj remains clean and tidy with no extra entries compared with when the project was first created
Actual: VS has added the following:

  <ItemGroup>
    <None Remove="Program.cs.blah" />
  </ItemGroup>

  <ItemGroup>
    <Compile Include="Program.cs.blah" />
  </ItemGroup>

Demo video

vs_copy_paste_bug

Why this matters

  1. It's bad to produce nonsense in the csproj that developers have to revert manually or might accidentally commit to source control.
  2. When the csproj contains these bogus <Compile> entries, it causes any number of problems in the SDK. For example, if you have an extra entry for SomeFile.razor.css, then the Razor SDK will give a compile error saying you have duplicate .razor.css file entries (because you actually do).

@davkean Can you suggest where would be best to report this? Is this part of the project system something that you work on?

@SteveSandersonMS SteveSandersonMS added External This is an issue in a component not contained in this repository. It is open for tracking purposes. and removed investigate labels Sep 24, 2020
@davkean
Copy link
Member

davkean commented Sep 24, 2020

See my comment here: #24790 (comment). This behavior is as per the original design.

  • The default SDK has a glob similar to <None Include="*.*" Exclude="*.cs" />
  • When you rename the .cs file to "blah", it tries to maintain the existing item type via <Compile Include="Program.cs.blah" />, but if it was to do that - it would now be included in two items; None and Compile.
  • It adds the None Remove="Program.cs.blah" /> to prevent that.

There is likely something in the default globs for the SDK you are using that that includes .css files in the None item, resulting in above.

@davkean
Copy link
Member

davkean commented Sep 24, 2020

Here is the bug:

By default, VS says .css files end up in the <Content/> item type: https://github.com/dotnet/project-system/blob/master/src/Microsoft.VisualStudio.ProjectSystem.Managed/ProjectSystem/Rules/Items/ProjectItemsSchema.xaml#L27.

The Web inherits the .NET SDK which says that .css files outside of wwwroot end up in the <None /> item. That is the cause.

What item type do you want these css? That will determine the owner of the bug.

@SteveSandersonMS
Copy link
Member Author

SteveSandersonMS commented Sep 24, 2020

OK, thanks for clarifying. So if I follow this correctly, this issue will occur when a developer:

  • Copy/pastes a .css file from inside wwwroot to outside it (or vice-versa)
  • Or, renames a compile-type file (e.g., .cs) to .css anywhere

... because in both cases VS is trying to preserve the original file's categorisation. If so, the mechanics of the issue do make sense, so thanks very much for clarifying the details!

To be honest I do question the design of trying to preserve the file type when pasting or renaming. It feels like it's a hangover from an earlier era where project files listed every single item. In the newer world where project files don't list every file explicitly but rather match based on patterns, it's really uncommon for any developer to want to create single-file exceptions to the normal build rules. I personally suspect it's far more common, when renaming a file, that the developer's intent is to change the file type, not to create a special exception where the file has a different type than implied by its extension/location. Apologies if I'm missing awareness of some common cases where people do want that, I just can't think of any from my own experience 😄

What item type do you want these css? That will determine the owner of the bug.

I don't want to change the build configuration. If wwwroot/**/*.css is historically Content, and other .css is historically None, then I guess that has to remain the case to avoid breaking people's builds.

What I would ideally like is for VS not to try to generate exceptions to these rules implicitly when people perform common gestures like copy or rename (similar to how VS Code does not do that). But I appreciate you may have reasons that I don't know about why it's important for VS to do so.

@SteveSandersonMS
Copy link
Member Author

@dotnet/aspnet-blazor-eng I'm closing this as external.

@ghost ghost locked as resolved and limited conversation to collaborators Oct 25, 2020
@dotnet dotnet unlocked this conversation Nov 18, 2020
@dotnet dotnet locked and limited conversation to collaborators Nov 18, 2020
@mkArtakMSFT
Copy link
Member

Filed an internal issue to track this.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates External This is an issue in a component not contained in this repository. It is open for tracking purposes.
Projects
None yet
Development

No branches or pull requests

7 participants