diff --git a/src/Mvc/Mvc.TagHelpers/src/ComponentTagHelper.cs b/src/Mvc/Mvc.TagHelpers/src/ComponentTagHelper.cs
index 6dc9bfe722..4bac5c8fc7 100644
--- a/src/Mvc/Mvc.TagHelpers/src/ComponentTagHelper.cs
+++ b/src/Mvc/Mvc.TagHelpers/src/ComponentTagHelper.cs
@@ -14,14 +14,16 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
///
/// A that renders a Razor component.
///
- [HtmlTargetElement("component", Attributes = ComponentTypeName, TagStructure = TagStructure.WithoutEndTag)]
+ [HtmlTargetElement(TagHelperName, Attributes = ComponentTypeName, TagStructure = TagStructure.WithoutEndTag)]
public sealed class ComponentTagHelper : TagHelper
{
+ private const string TagHelperName = "component";
private const string ComponentParameterName = "params";
private const string ComponentParameterPrefix = "param-";
private const string ComponentTypeName = "type";
private const string RenderModeName = "render-mode";
private IDictionary _parameters;
+ private RenderMode? _renderMode;
///
/// Gets or sets the for the current request.
@@ -54,7 +56,29 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
/// Gets or sets the
///
[HtmlAttributeName(RenderModeName)]
- public RenderMode RenderMode { get; set; }
+ public RenderMode RenderMode
+ {
+ get => _renderMode ?? default;
+ set
+ {
+ switch (value)
+ {
+ case RenderMode.Server:
+ case RenderMode.ServerPrerendered:
+ case RenderMode.Static:
+ _renderMode = value;
+ break;
+
+ default:
+ throw new ArgumentException(
+ message: Resources.FormatInvalidEnumArgument(
+ nameof(value),
+ value,
+ typeof(RenderMode).FullName),
+ paramName: nameof(value));
+ }
+ }
+ }
///
public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
@@ -69,6 +93,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
throw new ArgumentNullException(nameof(output));
}
+ if (_renderMode is null)
+ {
+ throw new ArgumentException(Resources.FormatAttributeIsRequired(RenderModeName, TagHelperName), nameof(RenderMode));
+ }
+
var componentRenderer = ViewContext.HttpContext.RequestServices.GetRequiredService();
var result = await componentRenderer.RenderComponentAsync(ViewContext, ComponentType, RenderMode, _parameters);
diff --git a/src/Mvc/Mvc.TagHelpers/src/Resources.resx b/src/Mvc/Mvc.TagHelpers/src/Resources.resx
index 96c56dff7f..7a69f0d95f 100644
--- a/src/Mvc/Mvc.TagHelpers/src/Resources.resx
+++ b/src/Mvc/Mvc.TagHelpers/src/Resources.resx
@@ -162,4 +162,7 @@
The fallback partial view '{0}' was not found. The following locations were searched:{1}
+
+ A value for the '{0}' attribute must be supplied to the '{1}' tag helper.
+
\ No newline at end of file
diff --git a/src/Mvc/Mvc.TagHelpers/test/ComponentTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/ComponentTagHelperTest.cs
index 5c1aff4a7e..fe8db979bd 100644
--- a/src/Mvc/Mvc.TagHelpers/test/ComponentTagHelperTest.cs
+++ b/src/Mvc/Mvc.TagHelpers/test/ComponentTagHelperTest.cs
@@ -3,13 +3,13 @@
using System;
using System.Collections.Generic;
-using System.IO.Pipes;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
+using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Xunit;
@@ -25,6 +25,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var tagHelper = new ComponentTagHelper
{
ViewContext = GetViewContext(),
+ RenderMode = RenderMode.Static,
};
var context = GetTagHelperContext();
var output = GetTagHelperOutput();
@@ -38,6 +39,24 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
Assert.Null(output.TagName);
}
+ [Fact]
+ public async Task ProcessAsync_WithoutSpecifyingRenderMode_ThrowsError()
+ {
+ // Arrange
+ var tagHelper = new ComponentTagHelper
+ {
+ ViewContext = GetViewContext(),
+ };
+ var context = GetTagHelperContext();
+ var output = GetTagHelperOutput();
+
+ // Act & Assert
+ await ExceptionAssert.ThrowsArgumentAsync(
+ () => tagHelper.ProcessAsync(context, output),
+ nameof(RenderMode),
+ "A value for the 'render-mode' attribute must be supplied to the 'component' tag helper.");
+ }
+
private static TagHelperContext GetTagHelperContext()
{
return new TagHelperContext(