Better error handling when setting properties on child components
This commit is contained in:
parent
3940ca8b60
commit
9f7dab3096
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
Loading…
Reference in New Issue