diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorDesignTimeNodeWriter.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorDesignTimeNodeWriter.cs
index d067eebc63..3ed8d0959c 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorDesignTimeNodeWriter.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorDesignTimeNodeWriter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -422,7 +422,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor
context.CodeWriter.Write(" = ");
// If we have a parameter type, then add a type check.
- if (node.BoundAttribute != null)
+ if (node.BoundAttribute != null && !node.BoundAttribute.IsWeaklyTyped())
{
context.CodeWriter.Write(BlazorApi.RuntimeHelpers.TypeCheck);
context.CodeWriter.Write("<");
@@ -436,7 +436,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor
WriteCSharpToken(context, tokens[i]);
}
- if (node.BoundAttribute != null)
+ if (node.BoundAttribute != null && !node.BoundAttribute.IsWeaklyTyped())
{
context.CodeWriter.Write(")");
}
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorMetadata.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorMetadata.cs
index 95f2cb52b4..673ae9f504 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorMetadata.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorMetadata.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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.
namespace Microsoft.AspNetCore.Blazor.Razor
@@ -30,6 +30,8 @@ namespace Microsoft.AspNetCore.Blazor.Razor
{
public static readonly string DelegateSignatureKey = "Blazor.DelegateSignature";
+ public static readonly string WeaklyTypedKey = "Blazor.IsWeaklyTyped";
+
public static readonly string RuntimeName = "Blazor.IComponent";
public readonly static string TagHelperKind = "Blazor.Component";
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorRuntimeNodeWriter.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorRuntimeNodeWriter.cs
index b91431ad1b..547d763cc0 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorRuntimeNodeWriter.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/BlazorRuntimeNodeWriter.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -379,7 +379,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor
}
else
{
- if (node.BoundAttribute != null)
+ if (node.BoundAttribute != null && !node.BoundAttribute.IsWeaklyTyped())
{
context.CodeWriter.Write(BlazorApi.RuntimeHelpers.TypeCheck);
context.CodeWriter.Write("<");
@@ -393,7 +393,7 @@ namespace Microsoft.AspNetCore.Blazor.Razor
context.CodeWriter.Write(tokens[i].Content);
}
- if (node.BoundAttribute != null)
+ if (node.BoundAttribute != null && !node.BoundAttribute.IsWeaklyTyped())
{
context.CodeWriter.Write(")");
}
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/EventHandlerTagHelperDescriptorProvider.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/EventHandlerTagHelperDescriptorProvider.cs
index 457d31465e..ccb307d677 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/EventHandlerTagHelperDescriptorProvider.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/EventHandlerTagHelperDescriptorProvider.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -143,6 +143,10 @@ namespace Microsoft.AspNetCore.Blazor.Razor
// Use a string here so that we get HTML context by default.
a.TypeName = typeof(string).FullName;
+ // But make this weakly typed (don't type check) - delegates have their own type-checking
+ // logic that we don't want to interfere with.
+ a.Metadata.Add(BlazorMetadata.Component.WeaklyTypedKey, bool.TrueString);
+
// WTE has a bug 15.7p1 where a Tag Helper without a display-name that looks like
// a C# property will crash trying to create the toolips.
a.SetPropertyName(entry.Attribute);
diff --git a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/TagHelperBoundAttributeDescriptorExtensions.cs b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/TagHelperBoundAttributeDescriptorExtensions.cs
index 504eb0d04e..59cf7e1880 100644
--- a/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/TagHelperBoundAttributeDescriptorExtensions.cs
+++ b/src/Microsoft.AspNetCore.Blazor.Razor.Extensions/TagHelperBoundAttributeDescriptorExtensions.cs
@@ -1,4 +1,4 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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;
@@ -20,5 +20,18 @@ namespace Microsoft.AspNetCore.Blazor.Razor
attribute.Metadata.TryGetValue(key, out var value) &&
string.Equals(value, bool.TrueString);
}
+
+ public static bool IsWeaklyTyped(this BoundAttributeDescriptor attribute)
+ {
+ if (attribute == null)
+ {
+ throw new ArgumentNullException(nameof(attribute));
+ }
+
+ var key = BlazorMetadata.Component.WeaklyTypedKey;
+ return
+ attribute.Metadata.TryGetValue(key, out var value) &&
+ string.Equals(value, bool.TrueString);
+ }
}
}
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs
index 2832cb83e5..facfb1abdf 100644
--- a/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/DesignTimeCodeGenerationTest.cs
@@ -174,6 +174,40 @@ namespace Test
CompileToAssembly(generated);
}
+ // Regression test for #954 - we need to allow arbitrary event handler
+ // attributes with weak typing.
+ [Fact]
+ public void ChildComponent_WithWeaklyTypeEventHandler()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(Parse(@"
+using System;
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class DynamicElement : BlazorComponent
+ {
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+
+
+@functions {
+ private Action OnClick { get; set; }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
[Fact]
public void ChildComponent_WithExplicitEventHandler()
{
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs
index d57e1bcb91..b381d87d7c 100644
--- a/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/RuntimeCodeGenerationTest.cs
@@ -166,6 +166,40 @@ namespace Test
CompileToAssembly(generated);
}
+ // Regression test for #954 - we need to allow arbitrary event handler
+ // attributes with weak typing.
+ [Fact]
+ public void ChildComponent_WithWeaklyTypeEventHandler()
+ {
+ // Arrange
+ AdditionalSyntaxTrees.Add(Parse(@"
+using System;
+using Microsoft.AspNetCore.Blazor;
+using Microsoft.AspNetCore.Blazor.Components;
+
+namespace Test
+{
+ public class DynamicElement : BlazorComponent
+ {
+ }
+}
+"));
+
+ // Act
+ var generated = CompileToCSharp(@"
+@addTagHelper *, TestAssembly
+
+
+@functions {
+ private Action OnClick { get; set; }
+}");
+
+ // Assert
+ AssertDocumentNodeMatchesBaseline(generated.CodeDocument);
+ AssertCSharpDocumentMatchesBaseline(generated.CodeDocument);
+ CompileToAssembly(generated);
+ }
+
[Fact]
public void ChildComponent_WithExplicitEventHandler()
{
@@ -759,8 +793,6 @@ Welcome to your new app.
[Fact] // https://github.com/aspnet/Blazor/issues/773
public void Regression_773()
{
- GenerateBaselines = true;
-
// Arrange
AdditionalSyntaxTrees.Add(Parse(@"
using Microsoft.AspNetCore.Blazor.Components;
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.codegen.cs
new file mode 100644
index 0000000000..64eaf8d5aa
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.codegen.cs
@@ -0,0 +1,49 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Blazor;
+ using Microsoft.AspNetCore.Blazor.Components;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 219
+ private void __RazorDirectiveTokenHelpers__() {
+ ((System.Action)(() => {
+global::System.Object __typeHelper = "*, TestAssembly";
+ }
+ ))();
+ }
+ #pragma warning restore 219
+ #pragma warning disable 0414
+ private static System.Object __o = null;
+ #pragma warning restore 0414
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ __o = Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue(
+#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
+ OnClick
+
+#line default
+#line hidden
+ );
+ builder.AddAttribute(-1, "ChildContent", (Microsoft.AspNetCore.Blazor.RenderFragment)((builder2) => {
+ }
+ ));
+ }
+ #pragma warning restore 1998
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ private Action OnClick { get; set; }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.ir.txt
new file mode 100644
index 0000000000..604f3fa88e
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.ir.txt
@@ -0,0 +1,34 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [12] ) - System
+ UsingDirective - (18:2,1 [32] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [17] ) - System.Linq
+ UsingDirective - (73:4,1 [28] ) - System.Threading.Tasks
+ UsingDirective - (104:5,1 [33] ) - Microsoft.AspNetCore.Blazor
+ UsingDirective - (140:6,1 [44] ) - Microsoft.AspNetCore.Blazor.Components
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ DesignTimeDirective -
+ DirectiveToken - (14:0,14 [32] ) - "*, Microsoft.AspNetCore.Blazor"
+ DirectiveToken - (14:0,14 [9] ) - "*, Test"
+ DirectiveToken - (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml) - *, TestAssembly
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning disable 0414
+ CSharpCode -
+ IntermediateToken - - CSharp - private static System.Object __o = null;
+ CSharpCode -
+ IntermediateToken - - CSharp - #pragma warning restore 0414
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ HtmlContent - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (29:0,29 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
+ ComponentExtensionNode - (31:1,0 [37] x:\dir\subdir\Test\TestComponent.cshtml) - DynamicElement - Test.DynamicElement
+ ComponentAttributeExtensionNode - (56:1,25 [8] x:\dir\subdir\Test\TestComponent.cshtml) - onclick - onclick
+ CSharpExpression -
+ IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue(
+ IntermediateToken - (57:1,26 [7] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - OnClick
+ IntermediateToken - - CSharp - )
+ HtmlContent - (68:1,37 [4] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (68:1,37 [4] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n\n
+ CSharpCode - (84:3,12 [62] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (84:3,12 [62] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n private Action OnClick { get; set; }\n
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.mappings.txt
new file mode 100644
index 0000000000..ecad042f3e
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/DesignTimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.mappings.txt
@@ -0,0 +1,19 @@
+Source Location: (14:0,14 [15] x:\dir\subdir\Test\TestComponent.cshtml)
+|*, TestAssembly|
+Generated Location: (559:16,38 [15] )
+|*, TestAssembly|
+
+Source Location: (57:1,26 [7] x:\dir\subdir\Test\TestComponent.cshtml)
+|OnClick|
+Generated Location: (1201:30,26 [7] )
+|OnClick|
+
+Source Location: (84:3,12 [62] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ private Action OnClick { get; set; }
+|
+Generated Location: (1516:41,12 [62] )
+|
+ private Action OnClick { get; set; }
+|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.codegen.cs b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.codegen.cs
new file mode 100644
index 0000000000..5ec08178e3
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.codegen.cs
@@ -0,0 +1,31 @@
+//
+#pragma warning disable 1591
+namespace Test
+{
+ #line hidden
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Threading.Tasks;
+ using Microsoft.AspNetCore.Blazor;
+ using Microsoft.AspNetCore.Blazor.Components;
+ public class TestComponent : Microsoft.AspNetCore.Blazor.Components.BlazorComponent
+ {
+ #pragma warning disable 1998
+ protected override void BuildRenderTree(Microsoft.AspNetCore.Blazor.RenderTree.RenderTreeBuilder builder)
+ {
+ base.BuildRenderTree(builder);
+ builder.OpenComponent(0);
+ builder.AddAttribute(1, "onclick", Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue(OnClick));
+ builder.CloseComponent();
+ }
+ #pragma warning restore 1998
+#line 4 "x:\dir\subdir\Test\TestComponent.cshtml"
+
+ private Action OnClick { get; set; }
+
+#line default
+#line hidden
+ }
+}
+#pragma warning restore 1591
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.ir.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.ir.txt
new file mode 100644
index 0000000000..b432de290d
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.ir.txt
@@ -0,0 +1,20 @@
+Document -
+ NamespaceDeclaration - - Test
+ UsingDirective - (3:1,1 [14] ) - System
+ UsingDirective - (18:2,1 [34] ) - System.Collections.Generic
+ UsingDirective - (53:3,1 [19] ) - System.Linq
+ UsingDirective - (73:4,1 [30] ) - System.Threading.Tasks
+ UsingDirective - (104:5,1 [35] ) - Microsoft.AspNetCore.Blazor
+ UsingDirective - (140:6,1 [46] ) - Microsoft.AspNetCore.Blazor.Components
+ ClassDeclaration - - public - TestComponent - Microsoft.AspNetCore.Blazor.Components.BlazorComponent -
+ MethodDeclaration - - protected override - void - BuildRenderTree
+ CSharpCode -
+ IntermediateToken - - CSharp - base.BuildRenderTree(builder);
+ ComponentExtensionNode - (31:1,0 [37] x:\dir\subdir\Test\TestComponent.cshtml) - DynamicElement - Test.DynamicElement
+ ComponentAttributeExtensionNode - (56:1,25 [8] x:\dir\subdir\Test\TestComponent.cshtml) - onclick - onclick
+ CSharpExpression -
+ IntermediateToken - - CSharp - Microsoft.AspNetCore.Blazor.Components.BindMethods.GetEventHandlerValue(
+ IntermediateToken - (57:1,26 [7] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - OnClick
+ IntermediateToken - - CSharp - )
+ CSharpCode - (84:3,12 [62] x:\dir\subdir\Test\TestComponent.cshtml)
+ IntermediateToken - (84:3,12 [62] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n private Action OnClick { get; set; }\n
diff --git a/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.mappings.txt b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.mappings.txt
new file mode 100644
index 0000000000..4d99283766
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Blazor.Build.Test/TestFiles/RuntimeCodeGenerationTest/ChildComponent_WithWeaklyTypeEventHandler/TestComponent.mappings.txt
@@ -0,0 +1,9 @@
+Source Location: (84:3,12 [62] x:\dir\subdir\Test\TestComponent.cshtml)
+|
+ private Action OnClick { get; set; }
+|
+Generated Location: (989:23,12 [62] )
+|
+ private Action OnClick { get; set; }
+|
+
diff --git a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/EventHandlerTagHelperDescriptorProviderTest.cs b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/EventHandlerTagHelperDescriptorProviderTest.cs
index 8cf1910ae9..5f6d7959ad 100644
--- a/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/EventHandlerTagHelperDescriptorProviderTest.cs
+++ b/test/Microsoft.AspNetCore.Blazor.Razor.Extensions.Test/EventHandlerTagHelperDescriptorProviderTest.cs
@@ -1,6 +1,7 @@
-// Copyright (c) .NET Foundation. All rights reserved.
+// 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.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Razor.Language;
using Microsoft.CodeAnalysis.CSharp;
@@ -97,6 +98,11 @@ namespace Test
Assert.False(attribute.IsIndexerBooleanProperty);
Assert.False(attribute.IsIndexerStringProperty);
+ Assert.Collection(
+ attribute.Metadata.OrderBy(kvp => kvp.Key),
+ kvp => Assert.Equal(kvp, new KeyValuePair(BlazorMetadata.Component.WeaklyTypedKey, bool.TrueString)),
+ kvp => Assert.Equal(kvp, new KeyValuePair("Common.PropertyName", "onclick")));
+
Assert.Equal(
"Sets the 'onclick' attribute to the provided string or delegate value. " +
"A delegate value should be of type 'System.Action'.",