diff --git a/src/Microsoft.AspNet.Mvc.TagHelpers/Properties/Resources.Designer.cs b/src/Microsoft.AspNet.Mvc.TagHelpers/Properties/Resources.Designer.cs
index e167fc52c6..d0cae73f5e 100644
--- a/src/Microsoft.AspNet.Mvc.TagHelpers/Properties/Resources.Designer.cs
+++ b/src/Microsoft.AspNet.Mvc.TagHelpers/Properties/Resources.Designer.cs
@@ -122,6 +122,22 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
return string.Format(CultureInfo.CurrentCulture, GetString("InvalidEnumArgument"), p0, p1, p2);
}
+ ///
+ /// The attribute '{0}' does not exist in the {1}.
+ ///
+ internal static string TagHelperOutput_AttributeDoesNotExist
+ {
+ get { return GetString("TagHelperOutput_AttributeDoesNotExist"); }
+ }
+
+ ///
+ /// The attribute '{0}' does not exist in the {1}.
+ ///
+ internal static string FormatTagHelperOutput_AttributeDoesNotExist(object p0, object p1)
+ {
+ return string.Format(CultureInfo.CurrentCulture, GetString("TagHelperOutput_AttributeDoesNotExist"), p0, p1);
+ }
+
private static string GetString(string name, params string[] formatterNames)
{
var value = _resourceManager.GetString(name);
diff --git a/src/Microsoft.AspNet.Mvc.TagHelpers/Resources.resx b/src/Microsoft.AspNet.Mvc.TagHelpers/Resources.resx
index 1aa82d190f..8d7adbdb7d 100644
--- a/src/Microsoft.AspNet.Mvc.TagHelpers/Resources.resx
+++ b/src/Microsoft.AspNet.Mvc.TagHelpers/Resources.resx
@@ -138,4 +138,7 @@
The value of argument '{0}' ({1}) is invalid for Enum type '{2}'.
+
+ The attribute '{0}' does not exist in the {1}.
+
\ No newline at end of file
diff --git a/src/Microsoft.AspNet.Mvc.TagHelpers/TagHelperOutputExtensions.cs b/src/Microsoft.AspNet.Mvc.TagHelpers/TagHelperOutputExtensions.cs
index f72506bad2..e6a25d408a 100644
--- a/src/Microsoft.AspNet.Mvc.TagHelpers/TagHelperOutputExtensions.cs
+++ b/src/Microsoft.AspNet.Mvc.TagHelpers/TagHelperOutputExtensions.cs
@@ -35,8 +35,16 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
{
// We look for the original attribute so we can restore the exact attribute name the user typed.
// Approach also ignores changes made to tagHelperOutput[attributeName].
- var entry = context.AllAttributes.First(
+ var entry = context.AllAttributes.FirstOrDefault(
attribute => attribute.Key.Equals(attributeName, StringComparison.OrdinalIgnoreCase));
+
+ if (entry.Equals(default(KeyValuePair)))
+ {
+ throw new ArgumentException(
+ Resources.FormatTagHelperOutput_AttributeDoesNotExist(attributeName, nameof(TagHelperContext)),
+ nameof(attributeName));
+ }
+
tagHelperOutput.Attributes.Add(entry.Key, entry.Value);
}
}
diff --git a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TagHelperOutputExtensionsTest.cs b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TagHelperOutputExtensionsTest.cs
index 43cef4b14a..4fa6c957d0 100644
--- a/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TagHelperOutputExtensionsTest.cs
+++ b/test/Microsoft.AspNet.Mvc.TagHelpers.Test/TagHelperOutputExtensionsTest.cs
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;
+using Microsoft.AspNet.Testing;
using Microsoft.Framework.WebEncoders;
using Xunit;
@@ -79,6 +80,35 @@ namespace Microsoft.AspNet.Mvc.TagHelpers
Assert.Equal(expectedAttribute, attribute);
}
+ [Fact]
+ public void CopyHtmlAttribute_ThrowsWhenUnknownAttribute()
+ {
+ // Arrange
+ var invalidAttributeName = "hello2";
+ var tagHelperOutput = new TagHelperOutput(
+ "p",
+ attributes: new Dictionary());
+ var tagHelperContext = new TagHelperContext(
+ allAttributes: new Dictionary(StringComparer.Ordinal)
+ {
+ { "hello", "world" }
+ },
+ items: new Dictionary