diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/ContentBehaviorAttribute.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/ContentBehaviorAttribute.cs
new file mode 100644
index 0000000000..845e608151
--- /dev/null
+++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/ContentBehaviorAttribute.cs
@@ -0,0 +1,31 @@
+// 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;
+using Microsoft.AspNet.Razor.TagHelpers;
+
+namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
+{
+ ///
+ /// Used to override 's behavior when its
+ /// is invoked.
+ ///
+ [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
+ public sealed class ContentBehaviorAttribute : Attribute
+ {
+ ///
+ /// Instantiates a new instance of the class.
+ ///
+ /// The for the
+ /// .
+ public ContentBehaviorAttribute(ContentBehavior contentBehavior)
+ {
+ ContentBehavior = contentBehavior;
+ }
+
+ ///
+ /// for the .
+ ///
+ public ContentBehavior ContentBehavior { get; private set; }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs
index c7813265ca..fd1b02343c 100644
--- a/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs
+++ b/src/Microsoft.AspNet.Razor.Runtime/TagHelpers/TagHelperDescriptorFactory.cs
@@ -66,10 +66,14 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
return new TagHelperAttributeDescriptor(property.Name, property);
}
- // TODO: Make the content behavior pull from a ContentBehaviorAttribute: https://github.com/aspnet/Razor/issues/122
private static ContentBehavior GetContentBehavior(Type type)
{
- return ContentBehavior.None;
+ var typeInfo = type.GetTypeInfo();
+ var contentBehaviorAttribute = typeInfo.GetCustomAttribute(inherit: false);
+
+ return contentBehaviorAttribute != null ?
+ contentBehaviorAttribute.ContentBehavior :
+ ContentBehavior.None;
}
private static bool IsValidProperty(PropertyInfo property)
diff --git a/src/Microsoft.AspNet.Razor.Runtime/project.json b/src/Microsoft.AspNet.Razor.Runtime/project.json
index 58a82c4faf..052cfa9358 100644
--- a/src/Microsoft.AspNet.Razor.Runtime/project.json
+++ b/src/Microsoft.AspNet.Razor.Runtime/project.json
@@ -5,6 +5,10 @@
},
"frameworks": {
"net45": { },
- "aspnetcore50": { }
+ "aspnetcore50": {
+ "dependencies": {
+ "System.Reflection.Extensions": "4.0.0.0"
+ }
+ }
}
}
diff --git a/src/Microsoft.AspNet.Razor/TagHelpers/ContentBehavior.cs b/src/Microsoft.AspNet.Razor/TagHelpers/ContentBehavior.cs
index c513d5a710..b98be35f07 100644
--- a/src/Microsoft.AspNet.Razor/TagHelpers/ContentBehavior.cs
+++ b/src/Microsoft.AspNet.Razor/TagHelpers/ContentBehavior.cs
@@ -9,15 +9,14 @@ namespace Microsoft.AspNet.Razor.TagHelpers
public enum ContentBehavior
{
///
- /// Indicates that the tag helper will not modify its inner HTML in any way. This is the default
+ /// Indicates that a tag helper will not modify its content in any way. This is the default
/// .
///
/// Children of the current tag helper will execute after the current tag helper.
None,
///
- /// Indicates that the tag helper wants anything within its tag builder's inner HTML to be
- /// appended to content its children generate.
+ /// Indicates the tag helper's content should be appended to what its children generate.
///
/// Children of the current tag helper will execute before the current tag helper.
Append,
@@ -30,15 +29,13 @@ namespace Microsoft.AspNet.Razor.TagHelpers
Modify,
///
- /// Indicates that the tag helper wants anything within its tag builder's inner HTML to be
- /// prepended to the content its children generate.
+ /// Indicates the tag helper's content should be prepended to what its children generate.
///
/// Children of the current tag helper will execute after the current tag helper.
Prepend,
///
- /// Indicates that the tag helper wants anything within its tag builder's inner HTML to
- /// replace any HTML inside of it.
+ /// Indicates the tag helper's content should replace the HTML its children generate.
///
/// Children of the current tag helper will not execute.
Replace,
diff --git a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs
index 1dc078faa7..6fd0813131 100644
--- a/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs
+++ b/test/Microsoft.AspNet.Razor.Runtime.Test/TagHelpers/TagHelperDescriptorFactoryTest.cs
@@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
public class TagHelperDescriptorFactoryTest
{
[Fact]
- public void DescriptorFactory_BuildsDescriptorsFromSimpleTypes()
+ public void CreateDescriptor_BuildsDescriptorsFromSimpleTypes()
{
// Arrange
var expectedDescriptor = new TagHelperDescriptor("Object", "System.Object", ContentBehavior.None);
@@ -22,7 +22,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Fact]
- public void DescriptorFactory_BuildsDescriptorsWithConventionNames()
+ public void CreateDescriptor_BuildsDescriptorsWithConventionNames()
{
// Arrange
var intProperty = typeof(SingleAttributeTagHelper).GetProperty(nameof(SingleAttributeTagHelper.IntAttribute));
@@ -42,7 +42,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Fact]
- public void DescriptorFactory_OnlyAcceptsPropertiesWithGetAndSet()
+ public void CreateDescriptor_OnlyAcceptsPropertiesWithGetAndSet()
{
// Arrange
var validProperty = typeof(MissingAccessorTagHelper).GetProperty(
@@ -63,7 +63,7 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
}
[Fact]
- public void DescriptorFactory_OnlyAcceptsPropertiesWithPublicGetAndSet()
+ public void CreateDescriptor_OnlyAcceptsPropertiesWithPublicGetAndSet()
{
// Arrange
var validProperty = typeof(PrivateAccessorTagHelper).GetProperty(
@@ -83,5 +83,48 @@ namespace Microsoft.AspNet.Razor.Runtime.TagHelpers
// Assert
Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
}
+
+
+ [Fact]
+ public void CreateDescriptor_ResolvesCustomContentBehavior()
+ {
+ // Arrange
+ var expectedDescriptor = new TagHelperDescriptor(
+ "CustomContentBehavior",
+ typeof(CustomContentBehaviorTagHelper).FullName,
+ ContentBehavior.Append);
+
+ // Act
+ var descriptor = TagHelperDescriptorFactory.CreateDescriptor(typeof(CustomContentBehaviorTagHelper));
+
+ // Assert
+ Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
+ }
+
+ [Fact]
+ public void CreateDescriptor_DoesNotResolveInheritedCustomContentBehavior()
+ {
+ // Arrange
+ var expectedDescriptor = new TagHelperDescriptor(
+ "InheritedCustomContentBehavior",
+ typeof(InheritedCustomContentBehaviorTagHelper).FullName,
+ ContentBehavior.None);
+
+ // Act
+ var descriptor = TagHelperDescriptorFactory.CreateDescriptor(
+ typeof(InheritedCustomContentBehaviorTagHelper));
+
+ // Assert
+ Assert.Equal(descriptor, expectedDescriptor, CompleteTagHelperDescriptorComparer.Default);
+ }
+
+ [ContentBehavior(ContentBehavior.Append)]
+ private class CustomContentBehaviorTagHelper
+ {
+ }
+
+ private class InheritedCustomContentBehaviorTagHelper : CustomContentBehaviorTagHelper
+ {
+ }
}
}
\ No newline at end of file