diff --git a/src/Microsoft.AspNetCore.Razor/Compilation/TagHelpers/TagHelperDescriptor.cs b/src/Microsoft.AspNetCore.Razor/Compilation/TagHelpers/TagHelperDescriptor.cs index 77f5fa848..49286a3a5 100644 --- a/src/Microsoft.AspNetCore.Razor/Compilation/TagHelpers/TagHelperDescriptor.cs +++ b/src/Microsoft.AspNetCore.Razor/Compilation/TagHelpers/TagHelperDescriptor.cs @@ -17,9 +17,11 @@ public class TagHelperDescriptor private string _tagName; private string _typeName; private string _assemblyName; + private IDictionary _propertyBag; private IEnumerable _attributes = Enumerable.Empty(); - private IEnumerable _requiredAttributes = Enumerable.Empty(); + private IEnumerable _requiredAttributes = + Enumerable.Empty(); /// /// Text used as a required prefix when matching HTML start and end tags in the Razor source to available @@ -200,5 +202,21 @@ public IEnumerable RequiredAttributes /// tag helper. /// public TagHelperDesignTimeDescriptor DesignTimeDescriptor { get; set; } + + /// + /// A dictionary containing additional information about the . + /// + public IDictionary PropertyBag + { + get + { + if (_propertyBag == null) + { + _propertyBag = new Dictionary(); + } + + return _propertyBag; + } + } } } \ No newline at end of file diff --git a/test/Microsoft.AspNetCore.Razor.Test/Compilation/TagHelpers/TagHelperDescriptorTest.cs b/test/Microsoft.AspNetCore.Razor.Test/Compilation/TagHelpers/TagHelperDescriptorTest.cs index cc3747dce..10d28cd55 100644 --- a/test/Microsoft.AspNetCore.Razor.Test/Compilation/TagHelpers/TagHelperDescriptorTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Test/Compilation/TagHelpers/TagHelperDescriptorTest.cs @@ -2,6 +2,7 @@ // 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 Microsoft.AspNetCore.Razor.TagHelpers; using Microsoft.AspNetCore.Razor.Test.Internal; using Newtonsoft.Json; @@ -68,7 +69,8 @@ public void TagHelperDescriptor_CanBeSerialized() $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":{{" + $"\"{ nameof(TagHelperDesignTimeDescriptor.Summary) }\":\"usage summary\"," + $"\"{ nameof(TagHelperDesignTimeDescriptor.Remarks) }\":\"usage remarks\"," + - $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}}}"; + $"\"{ nameof(TagHelperDesignTimeDescriptor.OutputElementHint) }\":\"some-tag\"}}," + + $"\"{ nameof(TagHelperDescriptor.PropertyBag) }\":{{}}}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); @@ -132,7 +134,8 @@ public void TagHelperDescriptor_WithAttributes_CanBeSerialized() $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":1," + - $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null," + + $"\"{ nameof(TagHelperDescriptor.PropertyBag) }\":{{}}}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); @@ -200,7 +203,8 @@ public void TagHelperDescriptor_WithIndexerAttributes_CanBeSerialized() $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":[\"allowed child one\",\"allowed child two\"]," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":\"parent name\"," + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," + - $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null," + + $"\"{ nameof(TagHelperDescriptor.PropertyBag) }\":{{}}}}"; // Act var serializedDescriptor = JsonConvert.SerializeObject(descriptor); @@ -209,6 +213,43 @@ public void TagHelperDescriptor_WithIndexerAttributes_CanBeSerialized() Assert.Equal(expectedSerializedDescriptor, serializedDescriptor, StringComparer.Ordinal); } + [Fact] + public void TagHelperDescriptor_WithPropertyBagElements_CanBeSerialized() + { + // Arrange + var descriptor = new TagHelperDescriptor + { + Prefix = "prefix:", + TagName = "tag name", + TypeName = "type name", + AssemblyName = "assembly name" + }; + + descriptor.PropertyBag.Add("key one", "value one"); + descriptor.PropertyBag.Add("key two", "value two"); + + var expectedSerializedDescriptor = + $"{{\"{ nameof(TagHelperDescriptor.Prefix) }\":\"prefix:\"," + + $"\"{ nameof(TagHelperDescriptor.TagName) }\":\"tag name\"," + + $"\"{ nameof(TagHelperDescriptor.FullTagName) }\":\"prefix:tag name\"," + + $"\"{ nameof(TagHelperDescriptor.TypeName) }\":\"type name\"," + + $"\"{ nameof(TagHelperDescriptor.AssemblyName) }\":\"assembly name\"," + + $"\"{ nameof(TagHelperDescriptor.Attributes) }\":[]," + + $"\"{ nameof(TagHelperDescriptor.RequiredAttributes) }\":[]," + + $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + + $"\"{ nameof(TagHelperDescriptor.TagStructure) }\":0," + + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null," + + $"\"{ nameof(TagHelperDescriptor.PropertyBag) }\":" + + "{\"key one\":\"value one\",\"key two\":\"value two\"}}"; + + // Act + var serializedDescriptor = JsonConvert.SerializeObject(descriptor); + + // Assert + Assert.Equal(expectedSerializedDescriptor, serializedDescriptor); + } + [Fact] public void TagHelperDescriptor_CanBeDeserialized() { @@ -283,6 +324,7 @@ public void TagHelperDescriptor_CanBeDeserialized() expectedDescriptor.DesignTimeDescriptor, descriptor.DesignTimeDescriptor, TagHelperDesignTimeDescriptorComparer.Default); + Assert.Empty(descriptor.PropertyBag); } [Fact] @@ -354,6 +396,7 @@ public void TagHelperDescriptor_WithAttributes_CanBeDeserialized() Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.Attributes, descriptor.Attributes, TagHelperAttributeDescriptorComparer.Default); Assert.Empty(descriptor.RequiredAttributes); + Assert.Empty(descriptor.PropertyBag); } [Fact] @@ -385,7 +428,9 @@ public void TagHelperDescriptor_WithIndexerAttributes_CanBeDeserialized() $"\"{ nameof(TagHelperDescriptor.AllowedChildren) }\":null," + $"\"{ nameof(TagHelperDescriptor.RequiredParent) }\":null," + $"\"{nameof(TagHelperDescriptor.TagStructure)}\":1," + - $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null}}"; + $"\"{ nameof(TagHelperDescriptor.DesignTimeDescriptor) }\":null," + + $"\"{ nameof(TagHelperDescriptor.PropertyBag) }\":{{}}}}"; + var expectedDescriptor = new TagHelperDescriptor { Prefix = "prefix:", @@ -427,6 +472,44 @@ public void TagHelperDescriptor_WithIndexerAttributes_CanBeDeserialized() Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); Assert.Equal(expectedDescriptor.Attributes, descriptor.Attributes, TagHelperAttributeDescriptorComparer.Default); Assert.Empty(descriptor.RequiredAttributes); + Assert.Empty(descriptor.PropertyBag); + } + + [Fact] + public void TagHelperDescriptor_WithPropertyBagElements_CanBeDeserialized() + { + // Arrange + var serializedDescriptor = + $"{{\"{nameof(TagHelperDescriptor.Prefix)}\":\"prefix:\"," + + $"\"{nameof(TagHelperDescriptor.TagName)}\":\"tag name\"," + + $"\"{nameof(TagHelperDescriptor.TypeName)}\":\"type name\"," + + $"\"{nameof(TagHelperDescriptor.AssemblyName)}\":\"assembly name\"," + + $"\"{ nameof(TagHelperDescriptor.PropertyBag) }\":" + + "{\"key one\":\"value one\",\"key two\":\"value two\"}}"; + var expectedDescriptor = new TagHelperDescriptor + { + Prefix = "prefix:", + TagName = "tag name", + TypeName = "type name", + AssemblyName = "assembly name" + }; + + expectedDescriptor.PropertyBag.Add("key one", "value one"); + expectedDescriptor.PropertyBag.Add("key two", "value two"); + + // Act + var descriptor = JsonConvert.DeserializeObject(serializedDescriptor); + + // Assert + Assert.NotNull(descriptor); + Assert.Equal(expectedDescriptor.Prefix, descriptor.Prefix, StringComparer.Ordinal); + Assert.Equal(expectedDescriptor.TagName, descriptor.TagName, StringComparer.Ordinal); + Assert.Equal(expectedDescriptor.TypeName, descriptor.TypeName, StringComparer.Ordinal); + Assert.Equal(expectedDescriptor.AssemblyName, descriptor.AssemblyName, StringComparer.Ordinal); + Assert.Empty(descriptor.Attributes); + Assert.Empty(descriptor.RequiredAttributes); + Assert.Equal(expectedDescriptor.PropertyBag["key one"], descriptor.PropertyBag["key one"]); + Assert.Equal(expectedDescriptor.PropertyBag["key two"], descriptor.PropertyBag["key two"]); } } }