Better error handling when setting properties on child components

This commit is contained in:
Steve Sanderson 2018-01-26 10:10:06 -08:00
parent 3940ca8b60
commit 9f7dab3096
2 changed files with 56 additions and 3 deletions

View File

@ -104,9 +104,25 @@ namespace Microsoft.AspNetCore.Blazor.Rendering
private void SetPropertyOnComponent(IComponent component, in RenderTreeNode attributeNode)
{
// TODO: Cache the reflection
// TODO: Is it beneficial to cache the reflection?
var property = component.GetType().GetProperty(attributeNode.AttributeName);
property.SetValue(component, attributeNode.AttributeValue);
if (property == null)
{
throw new InvalidOperationException(
$"Component of type '{component.GetType().FullName}' does not have a property " +
$"matching the name '{attributeNode.AttributeName}'.");
}
try
{
property.SetValue(component, attributeNode.AttributeValue);
}
catch (Exception ex)
{
throw new InvalidOperationException(
$"Unable to set property '{attributeNode.AttributeName}' on component of " +
$"type '{component.GetType().FullName}'. The error was: {ex.Message}", ex);
}
}
}
}

View File

@ -702,9 +702,46 @@ namespace Microsoft.AspNetCore.Blazor.Test
}
[Fact]
public void RejectsUnknownPropertiesOnChildComponents()
public void ThrowsIfAssigningUnknownPropertiesToChildComponents()
{
// Arrange
var renderer = new FakeRenderer();
var oldTree = new RenderTreeBuilder(renderer);
var newTree = new RenderTreeBuilder(renderer);
var diff = new RenderTreeDiffComputer(renderer);
var testObject = new object();
newTree.OpenComponentElement<FakeComponent>(0);
newTree.AddAttribute(1, "SomeUnknownProperty", 123);
newTree.CloseElement();
// Act/Assert
var ex = Assert.Throws<InvalidOperationException>(() =>
{
diff.ApplyNewRenderTreeVersion(oldTree.GetNodes(), newTree.GetNodes());
});
Assert.Equal($"Component of type '{typeof(FakeComponent).FullName}' does not have a property matching the name 'SomeUnknownProperty'.", ex.Message);
}
[Fact]
public void ThrowsIfAssigningReadOnlyPropertiesToChildComponents()
{
// Arrange
var renderer = new FakeRenderer();
var oldTree = new RenderTreeBuilder(renderer);
var newTree = new RenderTreeBuilder(renderer);
var diff = new RenderTreeDiffComputer(renderer);
var testObject = new object();
newTree.OpenComponentElement<FakeComponent>(0);
newTree.AddAttribute(1, nameof(FakeComponent.ReadonlyProperty), 123);
newTree.CloseElement();
// Act/Assert
var ex = Assert.Throws<InvalidOperationException>(() =>
{
diff.ApplyNewRenderTreeVersion(oldTree.GetNodes(), newTree.GetNodes());
});
Assert.StartsWith($"Unable to set property '{nameof(FakeComponent.ReadonlyProperty)}' on " +
$"component of type '{typeof(FakeComponent).FullName}'.", ex.Message);
}
[Fact]