Preserve `class` casing when merging a `TagBuilder` into a `TagHelperOutput`
- #5313 Also: - preserve existing `TagHelperAttribute.ValueStyle` - fix this in `UrlResolutionTagHelper`, `LinkTagHelper`, and `ScriptTagHelper` as well - correct handling of non-`string` `classAttribute.Value`s in `TagHelperOutputExtensions` - relates to #3918 because new `ClassAttributeHtmlContent` is smaller than any concatenated attribute value nit: clean up `CacheTagHelper` whitespace and `using`s
This commit is contained in:
parent
0d782d9d9a
commit
27e4822a7b
|
|
@ -176,7 +176,10 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
|||
string resolvedUrl;
|
||||
if (TryResolveUrl(stringValue, resolvedUrl: out resolvedUrl))
|
||||
{
|
||||
output.Attributes[i] = new TagHelperAttribute(attribute.Name, resolvedUrl);
|
||||
output.Attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
resolvedUrl,
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -202,12 +205,18 @@ namespace Microsoft.AspNetCore.Mvc.Razor.TagHelpers
|
|||
IHtmlContent resolvedUrl;
|
||||
if (TryResolveUrl(stringValue, resolvedUrl: out resolvedUrl))
|
||||
{
|
||||
output.Attributes[i] = new TagHelperAttribute(attribute.Name, resolvedUrl);
|
||||
output.Attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
resolvedUrl,
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
else if (htmlString == null)
|
||||
{
|
||||
// Not a ~/ URL. Just avoid re-encoding the attribute value later.
|
||||
output.Attributes[i] = new TagHelperAttribute(attribute.Name, new HtmlString(stringValue));
|
||||
output.Attributes[i] = new TagHelperAttribute(
|
||||
attribute.Name,
|
||||
new HtmlString(stringValue),
|
||||
attribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Text.Encodings.Web;
|
||||
|
|
@ -94,8 +93,8 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
try
|
||||
{
|
||||
// The entry is set instead of assigning a value to the
|
||||
// task so that the expiration options are are not impacted
|
||||
// The entry is set instead of assigning a value to the
|
||||
// task so that the expiration options are are not impacted
|
||||
// by the time it took to compute it.
|
||||
|
||||
using (var entry = MemoryCache.CreateEntry(cacheKey))
|
||||
|
|
@ -118,7 +117,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
}
|
||||
finally
|
||||
{
|
||||
// If an exception occurs, ensure the other awaiters
|
||||
// If an exception occurs, ensure the other awaiters
|
||||
// render the output by themselves.
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -268,9 +268,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
if (Href != null)
|
||||
{
|
||||
var index = output.Attributes.IndexOfName(HrefAttributeName);
|
||||
var existingAttribute = output.Attributes[index];
|
||||
output.Attributes[index] = new TagHelperAttribute(
|
||||
HrefAttributeName,
|
||||
_fileVersionProvider.AddFileVersionToPath(Href));
|
||||
existingAttribute.Name,
|
||||
_fileVersionProvider.AddFileVersionToPath(Href),
|
||||
existingAttribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -234,10 +234,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
if (Src != null)
|
||||
{
|
||||
var index = output.Attributes.IndexOfName(SrcAttributeName);
|
||||
var existingAttribute = output.Attributes[index];
|
||||
output.Attributes[index] = new TagHelperAttribute(
|
||||
SrcAttributeName,
|
||||
existingAttribute.Name,
|
||||
_fileVersionProvider.AddFileVersionToPath(Src),
|
||||
output.Attributes[index].ValueStyle);
|
||||
existingAttribute.ValueStyle);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,11 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Encodings.Web;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Mvc.Rendering;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
|
|
@ -90,9 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
/// <param name="tagBuilder">The <see cref="TagBuilder"/> to merge attributes from.</param>
|
||||
/// <remarks>Existing <see cref="TagHelperOutput.Attributes"/> on the given <paramref name="tagHelperOutput"/>
|
||||
/// are not overridden; "class" attributes are merged with spaces.</remarks>
|
||||
public static void MergeAttributes(
|
||||
this TagHelperOutput tagHelperOutput,
|
||||
TagBuilder tagBuilder)
|
||||
public static void MergeAttributes(this TagHelperOutput tagHelperOutput, TagBuilder tagBuilder)
|
||||
{
|
||||
if (tagHelperOutput == null)
|
||||
{
|
||||
|
|
@ -110,18 +112,18 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
{
|
||||
tagHelperOutput.Attributes.Add(attribute.Key, attribute.Value);
|
||||
}
|
||||
else if (attribute.Key.Equals("class", StringComparison.OrdinalIgnoreCase))
|
||||
else if (string.Equals(attribute.Key, "class", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
TagHelperAttribute classAttribute;
|
||||
var found = tagHelperOutput.Attributes.TryGetAttribute("class", out classAttribute);
|
||||
Debug.Assert(found);
|
||||
|
||||
if (tagHelperOutput.Attributes.TryGetAttribute("class", out classAttribute))
|
||||
{
|
||||
tagHelperOutput.Attributes.SetAttribute("class", classAttribute.Value + " " + attribute.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
tagHelperOutput.Attributes.Add("class", attribute.Value);
|
||||
}
|
||||
var newAttribute = new TagHelperAttribute(
|
||||
classAttribute.Name,
|
||||
new ClassAttributeHtmlContent(classAttribute.Value, attribute.Value),
|
||||
classAttribute.ValueStyle);
|
||||
|
||||
tagHelperOutput.Attributes.SetAttribute(newAttribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -201,5 +203,63 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private class ClassAttributeHtmlContent : IHtmlContent
|
||||
{
|
||||
private readonly object _left;
|
||||
private readonly string _right;
|
||||
|
||||
public ClassAttributeHtmlContent(object left, string right)
|
||||
{
|
||||
_left = left;
|
||||
_right = right;
|
||||
}
|
||||
|
||||
public void WriteTo(TextWriter writer, HtmlEncoder encoder)
|
||||
{
|
||||
if (writer == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(writer));
|
||||
}
|
||||
|
||||
if (encoder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(encoder));
|
||||
}
|
||||
|
||||
// Write out "{left} {right}" in the common nothing-empty case.
|
||||
var wroteLeft = false;
|
||||
if (_left != null)
|
||||
{
|
||||
var htmlContent = _left as IHtmlContent;
|
||||
if (htmlContent != null)
|
||||
{
|
||||
// Ignore case where htmlContent is HtmlString.Empty. At worst, will add a leading space to the
|
||||
// generated attribute value.
|
||||
htmlContent.WriteTo(writer, encoder);
|
||||
wroteLeft = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
var stringValue = _left.ToString();
|
||||
if (!string.IsNullOrEmpty(stringValue))
|
||||
{
|
||||
encoder.Encode(writer, stringValue);
|
||||
wroteLeft = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(_right))
|
||||
{
|
||||
if (wroteLeft)
|
||||
{
|
||||
writer.Write(' ');
|
||||
}
|
||||
|
||||
encoder.Encode(writer, _right);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,7 +74,7 @@
|
|||
<input type="HtmlEncode[[radio]]" value="HtmlEncode[[Female]]" checked="HtmlEncode[[checked]]" id="HtmlEncode[[Customer_Gender]]" name="HtmlEncode[[Customer.Gender]]" /> Female
|
||||
<span class="HtmlEncode[[field-validation-valid]]" data-valmsg-for="HtmlEncode[[Customer.Gender]]" data-valmsg-replace="HtmlEncode[[true]]"></span>
|
||||
</div>
|
||||
<div class="HtmlEncode[[order validation-summary-valid]]" data-valmsg-summary="HtmlEncode[[true]]"><ul><li style="display:none"></li>
|
||||
<div class="order HtmlEncode[[validation-summary-valid]]" data-valmsg-summary="HtmlEncode[[true]]"><ul><li style="display:none"></li>
|
||||
</ul></div>
|
||||
<input type="HtmlEncode[[hidden]]" id="HtmlEncode[[Customer_Key]]" name="HtmlEncode[[Customer.Key]]" value="HtmlEncode[[KeyA]]" />
|
||||
<input type="submit" />
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Razor.TagHelpers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
{
|
||||
public class CaseSensitiveTagHelperAttributeComparer : IEqualityComparer<TagHelperAttribute>
|
||||
{
|
||||
public readonly static CaseSensitiveTagHelperAttributeComparer Default =
|
||||
new CaseSensitiveTagHelperAttributeComparer();
|
||||
|
||||
private CaseSensitiveTagHelperAttributeComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(TagHelperAttribute attributeX, TagHelperAttribute attributeY)
|
||||
{
|
||||
if (attributeX == attributeY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Normal comparer (TagHelperAttribute.Equals()) doesn't care about the Name case, in tests we do.
|
||||
return attributeX != null &&
|
||||
string.Equals(attributeX.Name, attributeY.Name, StringComparison.Ordinal) &&
|
||||
attributeX.ValueStyle == attributeY.ValueStyle &&
|
||||
(attributeX.ValueStyle == HtmlAttributeValueStyle.Minimized ||
|
||||
string.Equals(GetString(attributeX.Value), GetString(attributeY.Value)));
|
||||
}
|
||||
|
||||
public int GetHashCode(TagHelperAttribute attribute)
|
||||
{
|
||||
// Manually combine hash codes here. We can't reference HashCodeCombiner because we have internals visible
|
||||
// from Mvc.Core and Mvc.TagHelpers; both of which reference HashCodeCombiner.
|
||||
var baseHashCode = 0x1505L;
|
||||
var attributeHashCode = attribute.GetHashCode();
|
||||
var combinedHash = ((baseHashCode << 5) + baseHashCode) ^ attributeHashCode;
|
||||
var nameHashCode = StringComparer.Ordinal.GetHashCode(attribute.Name);
|
||||
combinedHash = ((combinedHash << 5) + combinedHash) ^ nameHashCode;
|
||||
|
||||
return combinedHash.GetHashCode();
|
||||
}
|
||||
|
||||
private string GetString(object value)
|
||||
{
|
||||
var htmlContent = value as IHtmlContent;
|
||||
if (htmlContent != null)
|
||||
{
|
||||
using (var writer = new StringWriter())
|
||||
{
|
||||
htmlContent.WriteTo(writer, NullHtmlEncoder.Default);
|
||||
return writer.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
return value?.ToString() ?? string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -489,7 +489,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
htmlGenerator.Verify();
|
||||
|
||||
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
|
||||
Assert.Equal(expectedAttributes, output.Attributes);
|
||||
Assert.Equal(expectedAttributes, output.Attributes, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
|
||||
|
|
@ -590,7 +590,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
htmlGenerator.Verify();
|
||||
|
||||
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
|
||||
Assert.Equal(expectedAttributes, output.Attributes);
|
||||
Assert.Equal(expectedAttributes, output.Attributes, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
|
||||
|
|
@ -684,7 +684,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
htmlGenerator.Verify();
|
||||
|
||||
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
|
||||
Assert.Equal(expectedAttributes, output.Attributes);
|
||||
Assert.Equal(expectedAttributes, output.Attributes, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
|
||||
|
|
@ -801,7 +801,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
htmlGenerator.Verify();
|
||||
|
||||
Assert.Equal(TagMode.StartTagOnly, output.TagMode);
|
||||
Assert.Equal(expectedAttributes, output.Attributes);
|
||||
Assert.Equal(expectedAttributes, output.Attributes, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(expectedPostContent, output.PostContent.GetContent());
|
||||
|
|
|
|||
|
|
@ -676,7 +676,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
},
|
||||
new TagHelperAttributeList
|
||||
{
|
||||
{ "class", "btn2 btn" }
|
||||
{ "clASS", "btn2 btn" }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -691,7 +691,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
},
|
||||
new TagHelperAttributeList
|
||||
{
|
||||
{ "class", "btn2 btn" }
|
||||
{ "clASS", "btn2 btn" }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -706,7 +706,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
},
|
||||
new TagHelperAttributeList
|
||||
{
|
||||
{ "class", "btn2 btn" }
|
||||
{ "clASS", "btn2 btn" }
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -725,7 +725,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
new TagHelperAttributeList
|
||||
{
|
||||
{ "before", "before value" },
|
||||
{ "class", "btn2 btn" },
|
||||
{ "clASS", "btn2 btn" },
|
||||
{ "mid", "mid value" },
|
||||
{ "after", "after value" },
|
||||
}
|
||||
|
|
@ -748,7 +748,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
new TagHelperAttributeList
|
||||
{
|
||||
{ "before", "before value" },
|
||||
{ "class", "btn2 btn" },
|
||||
{ "clASS", "btn2 btn" },
|
||||
{ "mid", "mid value" },
|
||||
{ "after", "after value" },
|
||||
{ "A", "A Value" },
|
||||
|
|
@ -833,7 +833,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
// Assert
|
||||
var attribute = Assert.Single(tagHelperOutput.Attributes);
|
||||
Assert.Equal(expectedAttribute, attribute);
|
||||
Assert.Equal(expectedAttribute, attribute, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
|
|
@ -859,7 +859,10 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
|
||||
// Assert
|
||||
var attribute = Assert.Single(tagHelperOutput.Attributes);
|
||||
Assert.Equal(new TagHelperAttribute(originalName, "Hello btn"), attribute);
|
||||
Assert.Equal(
|
||||
new TagHelperAttribute(originalName, "Hello btn"),
|
||||
attribute,
|
||||
CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -959,42 +962,5 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
attribute = Assert.Single(tagHelperOutput.Attributes, attr => attr.Name.Equals("for"));
|
||||
Assert.Equal(expectedBuilderAttribute.Value, attribute.Value);
|
||||
}
|
||||
|
||||
private class CaseSensitiveTagHelperAttributeComparer : IEqualityComparer<TagHelperAttribute>
|
||||
{
|
||||
public readonly static CaseSensitiveTagHelperAttributeComparer Default =
|
||||
new CaseSensitiveTagHelperAttributeComparer();
|
||||
|
||||
private CaseSensitiveTagHelperAttributeComparer()
|
||||
{
|
||||
}
|
||||
|
||||
public bool Equals(TagHelperAttribute attributeX, TagHelperAttribute attributeY)
|
||||
{
|
||||
if (attributeX == attributeY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Normal comparer (TagHelperAttribute.Equals()) doesn't care about the Name case, in tests we do.
|
||||
return attributeX != null &&
|
||||
string.Equals(attributeX.Name, attributeY.Name, StringComparison.Ordinal) &&
|
||||
attributeX.ValueStyle == attributeY.ValueStyle &&
|
||||
(attributeX.ValueStyle == HtmlAttributeValueStyle.Minimized || Equals(attributeX.Value, attributeY.Value));
|
||||
}
|
||||
|
||||
public int GetHashCode(TagHelperAttribute attribute)
|
||||
{
|
||||
// Manually combine hash codes here. We can't reference HashCodeCombiner because we have internals visible
|
||||
// from Mvc.Core and Mvc.TagHelpers; both of which reference HashCodeCombiner.
|
||||
var baseHashCode = 0x1505L;
|
||||
var attributeHashCode = attribute.GetHashCode();
|
||||
var combinedHash = ((baseHashCode << 5) + baseHashCode) ^ attributeHashCode;
|
||||
var nameHashCode = StringComparer.Ordinal.GetHashCode(attribute.Name);
|
||||
combinedHash = ((combinedHash << 5) + combinedHash) ^ nameHashCode;
|
||||
|
||||
return combinedHash.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var expectedTagName = "not-div";
|
||||
var metadataProvider = new TestModelMetadataProvider();
|
||||
var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
|
||||
var expectedAttributes = new TagHelperAttributeList
|
||||
{
|
||||
new TagHelperAttribute("class", "form-control validation-summary-valid"),
|
||||
new TagHelperAttribute("data-valmsg-summary", "true"),
|
||||
};
|
||||
|
||||
var expectedPreContent = "original pre-content";
|
||||
var expectedContent = "original content";
|
||||
|
|
@ -80,18 +85,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
output.Attributes,
|
||||
attribute =>
|
||||
{
|
||||
Assert.Equal("class", attribute.Name);
|
||||
Assert.Equal("form-control validation-summary-valid", attribute.Value);
|
||||
},
|
||||
attribute =>
|
||||
{
|
||||
Assert.Equal("data-valmsg-summary", attribute.Name);
|
||||
Assert.Equal("true", attribute.Value);
|
||||
});
|
||||
Assert.Equal(expectedAttributes, output.Attributes, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
|
|
@ -266,7 +260,11 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
// Assert
|
||||
Assert.InRange(output.Attributes.Count, low: 1, high: 2);
|
||||
var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class"));
|
||||
Assert.Equal("form-control validation-summary-errors", attribute.Value);
|
||||
Assert.Equal(
|
||||
new TagHelperAttribute("class", "form-control validation-summary-errors"),
|
||||
attribute,
|
||||
CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
|
|
@ -282,9 +280,14 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
var expectedError0 = "I am an error.";
|
||||
var expectedError2 = "I am also an error.";
|
||||
var expectedTagName = "not-div";
|
||||
var expectedAttributes = new TagHelperAttributeList
|
||||
{
|
||||
new TagHelperAttribute("class", "form-control validation-summary-errors"),
|
||||
new TagHelperAttribute("data-valmsg-summary", "true"),
|
||||
};
|
||||
|
||||
var metadataProvider = new TestModelMetadataProvider();
|
||||
var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
|
||||
|
||||
var validationSummaryTagHelper = new ValidationSummaryTagHelper(htmlGenerator)
|
||||
{
|
||||
ValidationSummary = ValidationSummary.All,
|
||||
|
|
@ -325,18 +328,7 @@ namespace Microsoft.AspNetCore.Mvc.TagHelpers
|
|||
await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);
|
||||
|
||||
// Assert
|
||||
Assert.Collection(
|
||||
output.Attributes,
|
||||
attribute =>
|
||||
{
|
||||
Assert.Equal("class", attribute.Name);
|
||||
Assert.Equal("form-control validation-summary-errors", attribute.Value);
|
||||
},
|
||||
attribute =>
|
||||
{
|
||||
Assert.Equal("data-valmsg-summary", attribute.Name);
|
||||
Assert.Equal("true", attribute.Value);
|
||||
});
|
||||
Assert.Equal(expectedAttributes, output.Attributes, CaseSensitiveTagHelperAttributeComparer.Default);
|
||||
Assert.Equal(expectedPreContent, output.PreContent.GetContent());
|
||||
Assert.Equal(expectedContent, output.Content.GetContent());
|
||||
Assert.Equal(
|
||||
|
|
|
|||
Loading…
Reference in New Issue