Add HtmlAttributeNameAttribute for TagHelpers.
- Added the ability to override the HTML attribute name for TagHelper properties. - Tested functionality of overriding the attribute name target and inheriting the attribute name. #121
This commit is contained in:
parent
a2a05e7153
commit
e5a21520e5
|
|
@ -94,6 +94,22 @@ namespace Microsoft.AspNet.Razor.Runtime
|
|||
return string.Format(CultureInfo.CurrentCulture, GetString("TagNameAttribute_AdditionalTagsCannotContainNull"), p0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value cannot be null or empty.
|
||||
/// </summary>
|
||||
internal static string ArgumentCannotBeNullOrEmpty
|
||||
{
|
||||
get { return GetString("ArgumentCannotBeNullOrEmpty"); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The value cannot be null or empty.
|
||||
/// </summary>
|
||||
internal static string FormatArgumentCannotBeNullOrEmpty()
|
||||
{
|
||||
return GetString("ArgumentCannotBeNullOrEmpty");
|
||||
}
|
||||
|
||||
private static string GetString(string name, params string[] formatterNames)
|
||||
{
|
||||
var value = _resourceManager.GetString(name);
|
||||
|
|
|
|||
|
|
@ -134,4 +134,7 @@
|
|||
<data name="TagNameAttribute_AdditionalTagsCannotContainNull" xml:space="preserve">
|
||||
<value>Parameter {0} must not contain null tag names.</value>
|
||||
</data>
|
||||
<data name="ArgumentCannotBeNullOrEmpty" xml:space="preserve">
|
||||
<value>The value cannot be null or empty.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to override an <see cref="ITagHelper"/> property's HTML attribute name.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
|
||||
public sealed class HtmlAttributeNameAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// Instantiates a new instance of the <see cref="HtmlAttributeNameAttribute"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">HTML attribute name for the associated property.</param>
|
||||
public HtmlAttributeNameAttribute(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentException(Resources.ArgumentCannotBeNullOrEmpty, nameof(name));
|
||||
}
|
||||
|
||||
Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HTML attribute name of the associated property.
|
||||
/// </summary>
|
||||
public string Name { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -68,11 +68,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
return attributeDescriptors;
|
||||
}
|
||||
|
||||
// TODO: Make the HTML attribute name support names from a AttributeNameAttribute:
|
||||
// https://github.com/aspnet/Razor/issues/121
|
||||
private static TagHelperAttributeDescriptor ToAttributeDescriptor(PropertyInfo property)
|
||||
{
|
||||
return new TagHelperAttributeDescriptor(property.Name, property);
|
||||
var attributeNameAttribute = property.GetCustomAttribute<HtmlAttributeNameAttribute>(inherit: false);
|
||||
var attributeName = attributeNameAttribute != null ?
|
||||
attributeNameAttribute.Name :
|
||||
property.Name;
|
||||
|
||||
return new TagHelperAttributeDescriptor(attributeName, property);
|
||||
}
|
||||
|
||||
private static ContentBehavior GetContentBehavior(Type type)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using Microsoft.Internal.Web.Utils;
|
|||
|
||||
namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
||||
{
|
||||
public class CompleteTagHelperDescriptorComparer : TagHelperDescriptorComparer
|
||||
public class CompleteTagHelperDescriptorComparer : TagHelperDescriptorComparer, IEqualityComparer<TagHelperDescriptor>
|
||||
{
|
||||
public new static readonly CompleteTagHelperDescriptorComparer Default =
|
||||
new CompleteTagHelperDescriptorComparer();
|
||||
|
|
@ -17,14 +17,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
{
|
||||
}
|
||||
|
||||
public new bool Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||
bool IEqualityComparer<TagHelperDescriptor>.Equals(TagHelperDescriptor descriptorX, TagHelperDescriptor descriptorY)
|
||||
{
|
||||
return base.Equals(descriptorX, descriptorY) &&
|
||||
descriptorX.Attributes.SequenceEqual(descriptorY.Attributes,
|
||||
CompleteTagHelperAttributeDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
public new int GetHashCode(TagHelperDescriptor descriptor)
|
||||
int IEqualityComparer<TagHelperDescriptor>.GetHashCode(TagHelperDescriptor descriptor)
|
||||
{
|
||||
return HashCodeCombiner.Start()
|
||||
.Add(base.GetHashCode())
|
||||
|
|
|
|||
|
|
@ -8,6 +8,85 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
{
|
||||
public class TagHelperDescriptorFactoryTest
|
||||
{
|
||||
[Fact]
|
||||
public void CreateDescriptor_OverridesAttributeNameFromAttribute()
|
||||
{
|
||||
// Arrange
|
||||
var validProperty1 = typeof(OverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(OverriddenAttributeTagHelper.ValidAttribute1));
|
||||
var validProperty2 = typeof(OverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(OverriddenAttributeTagHelper.ValidAttribute2));
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor(
|
||||
"OverriddenAttribute",
|
||||
typeof(OverriddenAttributeTagHelper).FullName,
|
||||
ContentBehavior.None,
|
||||
new[] {
|
||||
new TagHelperAttributeDescriptor("SomethingElse", validProperty1),
|
||||
new TagHelperAttributeDescriptor("Something-Else", validProperty2)
|
||||
})
|
||||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(OverriddenAttributeTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_DoesNotInheritOverridenAttributeName()
|
||||
{
|
||||
// Arrange
|
||||
var validProperty1 = typeof(InheritedOverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedOverriddenAttributeTagHelper.ValidAttribute1));
|
||||
var validProperty2 = typeof(InheritedOverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedOverriddenAttributeTagHelper.ValidAttribute2));
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor(
|
||||
"InheritedOverriddenAttribute",
|
||||
typeof(InheritedOverriddenAttributeTagHelper).FullName,
|
||||
ContentBehavior.None,
|
||||
new[] {
|
||||
new TagHelperAttributeDescriptor(nameof(InheritedOverriddenAttributeTagHelper.ValidAttribute1),
|
||||
validProperty1),
|
||||
new TagHelperAttributeDescriptor("Something-Else", validProperty2)
|
||||
})
|
||||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(InheritedOverriddenAttributeTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_AllowsOverridenAttributeNameOnUnimplementedVirtual()
|
||||
{
|
||||
// Arrange
|
||||
var validProperty1 = typeof(InheritedNotOverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedNotOverriddenAttributeTagHelper.ValidAttribute1));
|
||||
var validProperty2 = typeof(InheritedNotOverriddenAttributeTagHelper).GetProperty(
|
||||
nameof(InheritedNotOverriddenAttributeTagHelper.ValidAttribute2));
|
||||
var expectedDescriptors = new[] {
|
||||
new TagHelperDescriptor(
|
||||
"InheritedNotOverriddenAttribute",
|
||||
typeof(InheritedNotOverriddenAttributeTagHelper).FullName,
|
||||
ContentBehavior.None,
|
||||
new[] {
|
||||
new TagHelperAttributeDescriptor("SomethingElse", validProperty1),
|
||||
new TagHelperAttributeDescriptor("Something-Else", validProperty2)
|
||||
})
|
||||
};
|
||||
|
||||
// Act
|
||||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(InheritedNotOverriddenAttributeTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CreateDescriptor_BuildsDescriptorsFromSimpleTypes()
|
||||
{
|
||||
|
|
@ -19,7 +98,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -41,7 +120,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -62,7 +141,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -84,7 +163,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -107,7 +186,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -124,7 +203,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -142,7 +221,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -171,7 +250,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(MultiTagTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(descriptors, expectedDescriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -192,7 +271,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
|
||||
// Assert
|
||||
var descriptor = Assert.Single(descriptors);
|
||||
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptor, descriptor, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -208,7 +287,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(DuplicateTagNameTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(descriptors, expectedDescriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -225,7 +304,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(OverrideNameTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(descriptors, expectedDescriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
@ -242,7 +321,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
var descriptors = TagHelperDescriptorFactory.CreateDescriptors(typeof(MultipleAttributeTagHelper));
|
||||
|
||||
// Assert
|
||||
Assert.Equal(descriptors, expectedDescriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
Assert.Equal(expectedDescriptors, descriptors, CompleteTagHelperDescriptorComparer.Default);
|
||||
}
|
||||
|
||||
[ContentBehavior(ContentBehavior.Append)]
|
||||
|
|
@ -283,5 +362,23 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
|
|||
private class InheritedSingleAttributeTagHelper : SingleAttributeTagHelper
|
||||
{
|
||||
}
|
||||
|
||||
private class OverriddenAttributeTagHelper
|
||||
{
|
||||
[HtmlAttributeName("SomethingElse")]
|
||||
public virtual string ValidAttribute1 { get; set; }
|
||||
|
||||
[HtmlAttributeName("Something-Else")]
|
||||
public string ValidAttribute2 { get; set; }
|
||||
}
|
||||
|
||||
private class InheritedOverriddenAttributeTagHelper : OverriddenAttributeTagHelper
|
||||
{
|
||||
public override string ValidAttribute1 { get; set; }
|
||||
}
|
||||
|
||||
private class InheritedNotOverriddenAttributeTagHelper : OverriddenAttributeTagHelper
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue