diff --git a/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs b/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs
index 62cfeb38a0..b6c137cfea 100644
--- a/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs
+++ b/src/Mvc/Mvc.ViewFeatures/ref/Microsoft.AspNetCore.Mvc.ViewFeatures.netcoreapp.cs
@@ -652,6 +652,7 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
[System.Diagnostics.DebuggerDisplayAttribute("{DebuggerToString()}")]
public partial class TagBuilder : Microsoft.AspNetCore.Html.IHtmlContent
{
+ public TagBuilder(Microsoft.AspNetCore.Mvc.Rendering.TagBuilder tagBuilder) { }
public TagBuilder(string tagName) { }
public Microsoft.AspNetCore.Mvc.ViewFeatures.AttributeDictionary Attributes { get { throw null; } }
public bool HasInnerHtml { get { throw null; } }
diff --git a/src/Mvc/Mvc.ViewFeatures/src/Rendering/TagBuilder.cs b/src/Mvc/Mvc.ViewFeatures/src/Rendering/TagBuilder.cs
index e3e4edfbb8..4b6d8b6fcb 100644
--- a/src/Mvc/Mvc.ViewFeatures/src/Rendering/TagBuilder.cs
+++ b/src/Mvc/Mvc.ViewFeatures/src/Rendering/TagBuilder.cs
@@ -37,6 +37,34 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
TagName = tagName;
}
+ ///
+ /// Creates a copy of the HTML tag passed as .
+ ///
+ /// Tag to copy.
+ public TagBuilder(TagBuilder tagBuilder)
+ {
+ if (tagBuilder == null)
+ {
+ throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(tagBuilder));
+ }
+
+ if (tagBuilder._attributes != null)
+ {
+ foreach (var tag in tagBuilder._attributes)
+ {
+ Attributes.Add(tag);
+ }
+ }
+
+ if (tagBuilder._innerHtml != null)
+ {
+ tagBuilder.InnerHtml.CopyTo(InnerHtml);
+ }
+
+ TagName = tagBuilder.TagName;
+ TagRenderMode = tagBuilder.TagRenderMode;
+ }
+
///
/// Gets the set of attributes that will be written to the tag.
///
diff --git a/src/Mvc/Mvc.ViewFeatures/test/Rendering/TagBuilderTest.cs b/src/Mvc/Mvc.ViewFeatures/test/Rendering/TagBuilderTest.cs
index 0132887614..3ceaeef37b 100644
--- a/src/Mvc/Mvc.ViewFeatures/test/Rendering/TagBuilderTest.cs
+++ b/src/Mvc/Mvc.ViewFeatures/test/Rendering/TagBuilderTest.cs
@@ -253,5 +253,64 @@ namespace Microsoft.AspNetCore.Mvc.Core.Rendering
// Assert
Assert.Equal("Hello", HtmlContentUtilities.HtmlContentToString(tag));
}
+
+ [Fact]
+ public void Constructor_Copy_CopiesTagRenderMode()
+ {
+ // Arrange
+ var originalTagBuilder = new TagBuilder("p");
+ originalTagBuilder.TagRenderMode = TagRenderMode.SelfClosing;
+
+ // Act
+ var clonedTagBuilder = new TagBuilder(originalTagBuilder);
+
+
+ // Assert
+ Assert.Equal(originalTagBuilder.TagRenderMode, clonedTagBuilder.TagRenderMode);
+ }
+
+ [Fact]
+ public void Constructor_Copy_DoesShallowCopyOfInnerHtml()
+ {
+ // Arrange
+ var originalTagBuilder = new TagBuilder("p");
+ originalTagBuilder.InnerHtml.AppendHtml("Hello");
+
+ // Act
+ var clonedTagBuilder = new TagBuilder(originalTagBuilder);
+
+ // Assert
+ Assert.NotEqual(originalTagBuilder.InnerHtml, clonedTagBuilder.InnerHtml);
+ Assert.Equal(HtmlContentUtilities.HtmlContentToString(originalTagBuilder.RenderBody()), HtmlContentUtilities.HtmlContentToString(clonedTagBuilder.RenderBody()));
+ }
+
+ [Fact]
+ public void Constructor_Copy_DoesShallowCopyOfAttributes()
+ {
+ // Arrange
+ var originalTagBuilder = new TagBuilder("p");
+ originalTagBuilder.AddCssClass("class1");
+
+ // Act
+ var clonedTagBuilder = new TagBuilder(originalTagBuilder);
+
+ // Assert
+ Assert.NotSame(originalTagBuilder.Attributes, clonedTagBuilder.Attributes);
+ Assert.Equal(originalTagBuilder.Attributes, clonedTagBuilder.Attributes);
+ }
+
+ [Fact]
+ public void Constructor_Copy_CopiesTagName()
+ {
+ // Arrange
+ var originalTagBuilder = new TagBuilder("p");
+
+ // Act
+
+ var clonedTagBuilder = new TagBuilder(originalTagBuilder);
+
+ // Assert
+ Assert.Equal(originalTagBuilder.TagName, clonedTagBuilder.TagName);
+ }
}
}
\ No newline at end of file