Skip to content

[Bug]: Setting ProjectMetadataElement.Name has weird behavior #10671

@dfederm

Description

@dfederm

Issue Description

If you update ProjectMetadataElement.Name, the project does not appear to actually change until some other operation happens which causes the model to rebuild. And once it does update, it appears to add a new metadata and leave the old one in place.

Steps to Reproduce

Project:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Build" Version="17.11.4" />
  </ItemGroup>
</Project>

Program.cs:

using System.Xml;
using Microsoft.Build.Construction;

string originalProjectContent = """
    <Project>
      <ItemGroup>
        <SomeItem Include="Foo" SomeMetadata="Value" />
      </ItemGroup>
    </Project>
    """;

Console.WriteLine("Original content:");
Console.WriteLine(originalProjectContent);
Console.WriteLine();

ProjectRootElement project;
using (XmlReader xmlReader = XmlReader.Create(new StringReader(originalProjectContent)))
{
    project = ProjectRootElement.Create(xmlReader);
}

ProjectItemElement item = project.Items.First();
ProjectMetadataElement metadata = item.Metadata.First();

Console.WriteLine("Changing metadata from 'SomeMetadata' to 'SomeOtherMetadata'");
Console.WriteLine();

metadata.Name = "SomeOtherMetadata";

Console.WriteLine("Updated content:");
Console.WriteLine(project.RawXml);
Console.WriteLine();

// Shenanigans
metadata.ExpressedAsAttribute = !metadata.ExpressedAsAttribute;
metadata.ExpressedAsAttribute = !metadata.ExpressedAsAttribute;

Console.WriteLine("Updated content 2:");
Console.WriteLine(project.RawXml);
Console.WriteLine();

Output:

>dotnet run
Original content:
<Project>
  <ItemGroup>
    <SomeItem Include="Foo" SomeMetadata="Value" />
  </ItemGroup>
</Project>

Changing metadata from 'SomeMetadata' to 'SomeOtherMetadata'

Updated content:
<Project>
  <ItemGroup>
    <SomeItem Include="Foo" SomeMetadata="Value" />
  </ItemGroup>
</Project>

Updated content 2:
<Project>
  <ItemGroup>
    <SomeItem Include="Foo" SomeMetadata="Value" SomeOtherMetadata="Value" />
  </ItemGroup>
</Project>

Expected Behavior

For the metadata's name to be updated.

Actual Behavior

Nothing happens at first. And then later a new metadata item is added and the existing one stays in place.

Analysis

No response

Versions & Configurations

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions