diff --git a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/TagBuilder.cs b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/TagBuilder.cs
index d97c6785e2..e3e4edfbb8 100644
--- a/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/TagBuilder.cs
+++ b/src/Microsoft.AspNetCore.Mvc.ViewFeatures/Rendering/TagBuilder.cs
@@ -298,37 +298,69 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
throw new ArgumentNullException(nameof(encoder));
}
- switch (TagRenderMode)
+ WriteTo(this, writer, encoder, TagRenderMode);
+ }
+
+ ///
+ /// Returns an that renders the body.
+ ///
+ /// An that renders the body.
+ public IHtmlContent RenderBody() => _innerHtml;
+
+ ///
+ /// Returns an that renders the start tag.
+ ///
+ /// An that renders the start tag.
+ public IHtmlContent RenderStartTag() => new RenderTagHtmlContent(this, TagRenderMode.StartTag);
+
+ ///
+ /// Returns an that renders the end tag.
+ ///
+ /// An that renders the end tag.
+ public IHtmlContent RenderEndTag() => new RenderTagHtmlContent(this, TagRenderMode.EndTag);
+
+ ///
+ /// Returns an that renders the self-closing tag.
+ ///
+ /// An that renders the self-closing tag.
+ public IHtmlContent RenderSelfClosingTag() => new RenderTagHtmlContent(this, TagRenderMode.SelfClosing);
+
+ private static void WriteTo(
+ TagBuilder tagBuilder,
+ TextWriter writer,
+ HtmlEncoder encoder,
+ TagRenderMode tagRenderMode)
+ {
+ switch (tagRenderMode)
{
case TagRenderMode.StartTag:
writer.Write("<");
- writer.Write(TagName);
- AppendAttributes(writer, encoder);
+ writer.Write(tagBuilder.TagName);
+ tagBuilder.AppendAttributes(writer, encoder);
writer.Write(">");
break;
case TagRenderMode.EndTag:
writer.Write("");
- writer.Write(TagName);
+ writer.Write(tagBuilder.TagName);
writer.Write(">");
break;
case TagRenderMode.SelfClosing:
writer.Write("<");
- writer.Write(TagName);
- AppendAttributes(writer, encoder);
+ writer.Write(tagBuilder.TagName);
+ tagBuilder.AppendAttributes(writer, encoder);
writer.Write(" />");
break;
default:
writer.Write("<");
- writer.Write(TagName);
- AppendAttributes(writer, encoder);
+ writer.Write(tagBuilder.TagName);
+ tagBuilder.AppendAttributes(writer, encoder);
writer.Write(">");
- if (_innerHtml != null)
+ if (tagBuilder._innerHtml != null)
{
- _innerHtml.WriteTo(writer, encoder);
+ tagBuilder._innerHtml.WriteTo(writer, encoder);
}
-
writer.Write("");
- writer.Write(TagName);
+ writer.Write(tagBuilder.TagName);
writer.Write(">");
break;
}
@@ -343,6 +375,23 @@ namespace Microsoft.AspNetCore.Mvc.Rendering
}
}
+ private class RenderTagHtmlContent : IHtmlContent
+ {
+ private readonly TagBuilder _tagBuilder;
+ private readonly TagRenderMode _tagRenderMode;
+
+ public RenderTagHtmlContent(TagBuilder tagBuilder, TagRenderMode tagRenderMode)
+ {
+ _tagBuilder = tagBuilder;
+ _tagRenderMode = tagRenderMode;
+ }
+
+ public void WriteTo(TextWriter writer, HtmlEncoder encoder)
+ {
+ TagBuilder.WriteTo(_tagBuilder, writer, encoder, _tagRenderMode);
+ }
+ }
+
private static class Html401IdUtil
{
public static bool IsAsciiLetter(char testChar)
diff --git a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Rendering/TagBuilderTest.cs b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Rendering/TagBuilderTest.cs
index 55a37da7e4..ce76a6c786 100644
--- a/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Rendering/TagBuilderTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.ViewFeatures.Test/Rendering/TagBuilderTest.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.IO;
using Microsoft.AspNetCore.Mvc.Rendering;
+using Microsoft.AspNetCore.Mvc.TestCommon;
using Microsoft.Extensions.WebEncoders.Testing;
using Xunit;
@@ -169,5 +170,89 @@ namespace Microsoft.AspNetCore.Mvc.Core.Rendering
Assert.False(tagBuilder.HasInnerHtml);
Assert.NotNull(innerHtml);
}
+
+ [Fact]
+ public void RenderStartTag_RendersExpectedStartTag()
+ {
+ // Arrange
+ var tagBuilder = new TagBuilder("p");
+
+ // Act
+ var tag = tagBuilder.RenderStartTag();
+
+ // Assert
+ Assert.Equal("
", HtmlContentUtilities.HtmlContentToString(tag));
+ }
+
+ [Fact]
+ public void RenderStartTag_RendersExpectedStartTag_TagBuilderRendersAsExpected()
+ {
+ // Arrange
+ var tagBuilder = new TagBuilder("p");
+ tagBuilder.TagRenderMode = TagRenderMode.EndTag;
+
+ // Act
+ var tag = tagBuilder.RenderStartTag();
+
+ // Assert
+ Assert.Equal("
", HtmlContentUtilities.HtmlContentToString(tag));
+ Assert.Equal("
", HtmlContentUtilities.HtmlContentToString(tagBuilder));
+ }
+
+ [Fact]
+ public void RenderEndTag_RendersExpectedEndTag()
+ {
+ // Arrange
+ var tagBuilder = new TagBuilder("p");
+
+ // Act
+ var tag = tagBuilder.RenderEndTag();
+
+ // Assert
+ Assert.Equal("", HtmlContentUtilities.HtmlContentToString(tag));
+ }
+
+ [Fact]
+ public void RenderEndTag_RendersExpectedEndTag_TagBuilderRendersAsExpected()
+ {
+ // Arrange
+ var tagBuilder = new TagBuilder("p");
+ tagBuilder.TagRenderMode = TagRenderMode.Normal;
+
+ // Act
+ var tag = tagBuilder.RenderEndTag();
+
+ // Assert
+ Assert.Equal("", HtmlContentUtilities.HtmlContentToString(tag));
+ Assert.Equal("", HtmlContentUtilities.HtmlContentToString(tagBuilder));
+ }
+
+ [Fact]
+ public void RenderSelfClosingTag_RendersExpectedSelfClosingTag()
+ {
+ // Arrange
+ var tagBuilder = new TagBuilder("p");
+
+ // Act
+ var tag = tagBuilder.RenderSelfClosingTag();
+
+ // Assert
+ Assert.Equal("", HtmlContentUtilities.HtmlContentToString(tag));
+
+ }
+
+ [Fact]
+ public void RenderBody_RendersExpectedBody()
+ {
+ // Arrange
+ var tagBuilder = new TagBuilder("p");
+ tagBuilder.InnerHtml.AppendHtml("Hello");
+
+ // Act
+ var tag = tagBuilder.RenderBody();
+
+ // Assert
+ Assert.Equal("Hello", HtmlContentUtilities.HtmlContentToString(tag));
+ }
}
}
\ No newline at end of file