diff --git a/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs b/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs
index e113dbcfaa..beb8475569 100644
--- a/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs
+++ b/src/Microsoft.AspNetCore.Mvc.Razor.Host/MvcRazorHost.cs
@@ -112,7 +112,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor
TagHelperContentGetContentMethodName = nameof(TagHelperContent.GetContent),
TagHelperOutputIsContentModifiedPropertyName = nameof(TagHelperOutput.IsContentModified),
TagHelperOutputContentPropertyName = nameof(TagHelperOutput.Content),
- TagHelperOutputGetChildContentAsyncMethodName = nameof(TagHelperExecutionContext.GetChildContentAsync)
+ TagHelperOutputGetChildContentAsyncMethodName = nameof(TagHelperOutput.GetChildContentAsync)
})
{
BeginContextMethodName = "BeginContext",
diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs
index c733fe11f8..07c3fdf6af 100644
--- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs
+++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/LinkTagHelper.cs
@@ -245,9 +245,6 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
return;
}
- // NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded.
- var attributes = new TagHelperAttributeList(output.Attributes);
-
if (AppendVersion == true)
{
EnsureFileVersionProvider();
@@ -264,7 +261,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
var builder = new DefaultTagHelperContent();
if (mode == Mode.GlobbedHref || mode == Mode.Fallback && !string.IsNullOrEmpty(HrefInclude))
{
- BuildGlobbedLinkTags(attributes, builder);
+ BuildGlobbedLinkTags(output.Attributes, builder);
if (string.IsNullOrEmpty(Href))
{
// Only HrefInclude is specified. Don't render the original tag.
@@ -306,8 +303,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
continue;
}
- attributes.SetAttribute(HrefAttributeName, url);
- BuildLinkTag(attributes, builder);
+ BuildLinkTag(url, attributes, builder);
}
}
@@ -402,38 +398,56 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
}
}
- private void BuildLinkTag(TagHelperAttributeList attributes, TagHelperContent builder)
+ private void BuildLinkTag(string href, TagHelperAttributeList attributes, TagHelperContent builder)
{
builder.AppendHtml("");
}
+ private void AppendVersionedHref(string hrefName, string hrefValue, TagHelperContent builder)
+ {
+ if (AppendVersion == true)
+ {
+ hrefValue = _fileVersionProvider.AddFileVersionToPath(hrefValue);
+ }
+
+ AppendAttribute(hrefName, hrefValue, builder);
+ }
+
+ private void AppendAttribute(string key, object value, TagHelperContent builder)
+ {
+ builder
+ .AppendHtml(key)
+ .AppendHtml("=\"")
+ .Append(HtmlEncoder, value)
+ .AppendHtml("\" ");
+ }
+
private enum Mode
{
///
diff --git a/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs b/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs
index 2935adb100..96ad174303 100644
--- a/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs
+++ b/src/Microsoft.AspNetCore.Mvc.TagHelpers/ScriptTagHelper.cs
@@ -208,9 +208,6 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
return;
}
- // NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded.
- var attributes = new TagHelperAttributeList(output.Attributes);
-
if (AppendVersion == true)
{
EnsureFileVersionProvider();
@@ -228,7 +225,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
if (mode == Mode.GlobbedSrc || mode == Mode.Fallback && !string.IsNullOrEmpty(SrcInclude))
{
- BuildGlobbedScriptTags(attributes, builder);
+ BuildGlobbedScriptTags(output.Attributes, builder);
if (string.IsNullOrEmpty(Src))
{
// Only SrcInclude is specified. Don't render the original tag.
@@ -245,7 +242,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
FallbackSrc = resolvedUrl;
}
- BuildFallbackBlock(attributes, builder);
+ BuildFallbackBlock(output.Attributes, builder);
}
output.PostElement.SetContent(builder);
@@ -270,8 +267,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
continue;
}
- attributes.SetAttribute(SrcAttributeName, url);
- BuildScriptTag(attributes, builder);
+ BuildScriptTag(url, attributes, builder);
}
}
@@ -288,13 +284,6 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
.AppendHtml(FallbackTestExpression)
.AppendHtml("||document.write(\"");
- // May have no "src" attribute in the dictionary e.g. if Src and SrcInclude were not bound.
- if (!attributes.ContainsName(SrcAttributeName))
- {
- // Need this entry to place each fallback source.
- attributes.Add(new TagHelperAttribute(SrcAttributeName, value: null));
- }
-
foreach (var src in fallbackSrcs)
{
// Fallback "src" values come from bound attributes and globbing. Must always be non-null.
@@ -302,6 +291,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
builder.AppendHtml("");
diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs
index 0ebf873016..5e4f3983dd 100644
--- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorPageTest.cs
@@ -978,13 +978,15 @@ namespace Microsoft.AspNetCore.Mvc.Razor
page.EndAddHtmlAttributeValues(executionContext);
// Assert
- var htmlAttribute = Assert.Single(executionContext.HtmlAttributes);
+ var output = executionContext.CreateTagHelperOutput();
+ var htmlAttribute = Assert.Single(output.Attributes);
Assert.Equal("someattr", htmlAttribute.Name, StringComparer.Ordinal);
var htmlContent = Assert.IsAssignableFrom(htmlAttribute.Value);
Assert.Equal(expectedValue, HtmlContentUtilities.HtmlContentToString(htmlContent), StringComparer.Ordinal);
Assert.False(htmlAttribute.Minimized);
- var allAttribute = Assert.Single(executionContext.AllAttributes);
+ var context = executionContext.CreateTagHelperContext();
+ var allAttribute = Assert.Single(context.AllAttributes);
Assert.Equal("someattr", allAttribute.Name, StringComparer.Ordinal);
htmlContent = Assert.IsAssignableFrom(allAttribute.Value);
Assert.Equal(expectedValue, HtmlContentUtilities.HtmlContentToString(htmlContent), StringComparer.Ordinal);
@@ -1016,8 +1018,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor
page.EndAddHtmlAttributeValues(executionContext);
// Assert
- Assert.Empty(executionContext.HtmlAttributes);
- var attribute = Assert.Single(executionContext.AllAttributes);
+ var output = executionContext.CreateTagHelperOutput();
+ Assert.Empty(output.Attributes);
+ var context = executionContext.CreateTagHelperContext();
+ var attribute = Assert.Single(context.AllAttributes);
Assert.Equal("someattr", attribute.Name, StringComparer.Ordinal);
Assert.Equal(expectedValue, (string)attribute.Value, StringComparer.Ordinal);
Assert.False(attribute.Minimized);
@@ -1044,11 +1048,13 @@ namespace Microsoft.AspNetCore.Mvc.Razor
page.EndAddHtmlAttributeValues(executionContext);
// Assert
- var htmlAttribute = Assert.Single(executionContext.HtmlAttributes);
+ var output = executionContext.CreateTagHelperOutput();
+ var htmlAttribute = Assert.Single(output.Attributes);
Assert.Equal("someattr", htmlAttribute.Name, StringComparer.Ordinal);
Assert.Equal("someattr", (string)htmlAttribute.Value, StringComparer.Ordinal);
Assert.False(htmlAttribute.Minimized);
- var allAttribute = Assert.Single(executionContext.AllAttributes);
+ var context = executionContext.CreateTagHelperContext();
+ var allAttribute = Assert.Single(context.AllAttributes);
Assert.Equal("someattr", allAttribute.Name, StringComparer.Ordinal);
Assert.Equal("someattr", (string)allAttribute.Value, StringComparer.Ordinal);
Assert.False(allAttribute.Minimized);
diff --git a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/RenderAtEndOfFormTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/RenderAtEndOfFormTagHelperTest.cs
index 17093ac74c..072a88bab0 100644
--- a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/RenderAtEndOfFormTagHelperTest.cs
+++ b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/RenderAtEndOfFormTagHelperTest.cs
@@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
});
var tagHelperContext = new TagHelperContext(
- Enumerable.Empty(),
+ new TagHelperAttributeList(),
new Dictionary