diff --git a/src/Components/Forms/src/EditContext.cs b/src/Components/Forms/src/EditContext.cs index ce5df0948125..8975f2d710da 100644 --- a/src/Components/Forms/src/EditContext.cs +++ b/src/Components/Forms/src/EditContext.cs @@ -95,7 +95,7 @@ public void NotifyValidationStateChanged() /// Identifies the field whose modification flag (if any) should be cleared. public void MarkAsUnmodified(in FieldIdentifier fieldIdentifier) { - if (_fieldStates.TryGetValue(fieldIdentifier, out var state)) + if (GetFieldState(fieldIdentifier) is { } state) { state.IsModified = false; } @@ -159,7 +159,7 @@ public IEnumerable GetValidationMessages() /// The current validation messages for the specified field. public IEnumerable GetValidationMessages(FieldIdentifier fieldIdentifier) { - if (_fieldStates.TryGetValue(fieldIdentifier, out var state)) + if (GetFieldState(fieldIdentifier) is { } state) { foreach (var message in state.GetValidationMessages()) { @@ -183,9 +183,7 @@ public IEnumerable GetValidationMessages(Expression> access /// /// True if the field has been modified; otherwise false. public bool IsModified(in FieldIdentifier fieldIdentifier) - => _fieldStates.TryGetValue(fieldIdentifier, out var state) - ? state.IsModified - : false; + => GetFieldState(fieldIdentifier)?.IsModified ?? false; /// /// Determines whether the specified fields in this has been modified. @@ -222,12 +220,14 @@ public bool Validate() internal FieldState? GetFieldState(in FieldIdentifier fieldIdentifier) { + ValidateFieldIdentifier(fieldIdentifier); _fieldStates.TryGetValue(fieldIdentifier, out var state); return state; } internal FieldState GetOrAddFieldState(in FieldIdentifier fieldIdentifier) { + ValidateFieldIdentifier(fieldIdentifier); if (!_fieldStates.TryGetValue(fieldIdentifier, out var state)) { state = new FieldState(fieldIdentifier); @@ -236,4 +236,14 @@ internal FieldState GetOrAddFieldState(in FieldIdentifier fieldIdentifier) return state; } + + private static void ValidateFieldIdentifier(in FieldIdentifier fieldIdentifier) + { + if (fieldIdentifier.Model is null || fieldIdentifier.FieldName is null) + { + throw new ArgumentException( + "The supplied FieldIdentifier is invalid. It must have a non-null Model and FieldName. This can happen when a component is not bound using @bind or the ValueExpression parameter is not supplied.", + nameof(fieldIdentifier)); + } + } } diff --git a/src/Components/Forms/test/EditContextTest.cs b/src/Components/Forms/test/EditContextTest.cs index c11700d14aa3..a1212fcbf138 100644 --- a/src/Components/Forms/test/EditContextTest.cs +++ b/src/Components/Forms/test/EditContextTest.cs @@ -121,6 +121,16 @@ public void RaisesEventWhenFieldIsChanged() // Assert Assert.True(didReceiveNotification); } + [Fact] + public void NotifyFieldChanged_ThrowsForInvalidFieldIdentifier() + { + var editContext = new EditContext(new object()); + + var ex = Assert.Throws(() => editContext.NotifyFieldChanged(default)); + + Assert.Equal("fieldIdentifier", ex.ParamName); + Assert.StartsWith("The supplied FieldIdentifier is invalid.", ex.Message); + } [Fact] public void CanEnumerateValidationMessagesAcrossAllStoresForSingleField()