diff --git a/src/Components/Components/src/Rendering/RenderTreeBuilder.cs b/src/Components/Components/src/Rendering/RenderTreeBuilder.cs
index 6876c97f0d..f8a28273e4 100644
--- a/src/Components/Components/src/Rendering/RenderTreeBuilder.cs
+++ b/src/Components/Components/src/Rendering/RenderTreeBuilder.cs
@@ -581,6 +581,14 @@ namespace Microsoft.AspNetCore.Components.Rendering
/// An integer that represents the position of the instruction in the source code.
public void OpenRegion(int sequence)
{
+ // We are entering a new scope, since we track the "duplicate attributes" per
+ // element/component we might need to clean them up now.
+ if (_hasSeenAddMultipleAttributes)
+ {
+ var indexOfLastElementOrComponent = _openElementIndices.Peek();
+ ProcessDuplicateAttributes(first: indexOfLastElementOrComponent + 1);
+ }
+
_openElementIndices.Push(_entries.Count);
Append(RenderTreeFrame.Region(sequence));
}
diff --git a/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs b/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs
index 7dfce8a79c..31364dca00 100644
--- a/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs
+++ b/src/Components/Components/test/Rendering/RenderTreeBuilderTest.cs
@@ -298,6 +298,39 @@ namespace Microsoft.AspNetCore.Components.Rendering
frame => AssertFrame.Attribute(frame, "attribute7", "the end"));
}
+ [Fact]
+ public void CanAddMultipleAttributes_WithChildRegion()
+ {
+ // This represents bug https://github.com/aspnet/AspNetCore/issues/16570
+ // If a sequence of attributes is terminated by a call to builder.OpenRegion,
+ // then the attribute deduplication logic wasn't working correctly
+
+ // Arrange
+ var builder = new RenderTreeBuilder();
+
+ // Act
+ builder.OpenElement(0, "myelement");
+ builder.AddAttribute(0, "attribute1", "value1");
+ builder.AddMultipleAttributes(1, new Dictionary()
+ {
+ { "attribute1", "value2" },
+ });
+ builder.OpenRegion(2);
+ builder.OpenElement(3, "child");
+ builder.CloseElement();
+ builder.CloseRegion();
+ builder.CloseElement();
+
+ // Assert
+ var frames = builder.GetFrames().AsEnumerable().ToArray();
+ Assert.Collection(
+ frames,
+ frame => AssertFrame.Element(frame, "myelement", 4),
+ frame => AssertFrame.Attribute(frame, "attribute1", "value2"),
+ frame => AssertFrame.Region(frame, 2, 2),
+ frame => AssertFrame.Element(frame, "child", 1, 3));
+ }
+
[Fact]
public void CanAddMultipleAttributes_DictionaryObject()
{