From 531662e72fef216e61e136d881da20d46ff96aa6 Mon Sep 17 00:00:00 2001 From: BharatRamsf3693 Date: Wed, 27 May 2026 17:44:19 +0530 Subject: [PATCH 1/5] Fix warning when using nullable properties in ValidationMessageStore.Add field accessor --- .../Forms/src/PublicAPI.Unshipped.txt | 4 ++ .../Forms/src/ValidationMessageStore.cs | 4 +- .../Forms/test/ValidationMessageStoreTest.cs | 66 +++++++++++++++++++ 3 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/Components/Forms/src/PublicAPI.Unshipped.txt b/src/Components/Forms/src/PublicAPI.Unshipped.txt index ae87cfab2ded..63be65eb9c3c 100644 --- a/src/Components/Forms/src/PublicAPI.Unshipped.txt +++ b/src/Components/Forms/src/PublicAPI.Unshipped.txt @@ -1,4 +1,8 @@ #nullable enable +*REMOVED*Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, string! message) -> void +*REMOVED*Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, System.Collections.Generic.IEnumerable! messages) -> void +Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, string! message) -> void +Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, System.Collections.Generic.IEnumerable! messages) -> void Microsoft.AspNetCore.Components.Forms.ValidationRequestedEventArgs.ValidationRequestedEventArgs(System.Threading.CancellationToken cancellationToken) -> void Microsoft.AspNetCore.Components.Forms.ValidationRequestedEventArgs.CancellationToken.get -> System.Threading.CancellationToken *REMOVED*static Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.AddDataAnnotationsValidation(this Microsoft.AspNetCore.Components.Forms.EditContext! editContext) -> Microsoft.AspNetCore.Components.Forms.EditContext! diff --git a/src/Components/Forms/src/ValidationMessageStore.cs b/src/Components/Forms/src/ValidationMessageStore.cs index 7fec1a18b654..9db1892e5acf 100644 --- a/src/Components/Forms/src/ValidationMessageStore.cs +++ b/src/Components/Forms/src/ValidationMessageStore.cs @@ -35,7 +35,7 @@ public void Add(in FieldIdentifier fieldIdentifier, string message) /// /// Identifies the field for which to add the message. /// The validation message. - public void Add(Expression> accessor, string message) + public void Add(Expression> accessor, string message) => Add(FieldIdentifier.Create(accessor), message); /// @@ -51,7 +51,7 @@ public void Add(in FieldIdentifier fieldIdentifier, IEnumerable messages /// /// Identifies the field for which to add the messages. /// The validation messages to be added. - public void Add(Expression> accessor, IEnumerable messages) + public void Add(Expression> accessor, IEnumerable messages) => Add(FieldIdentifier.Create(accessor), messages); /// diff --git a/src/Components/Forms/test/ValidationMessageStoreTest.cs b/src/Components/Forms/test/ValidationMessageStoreTest.cs index c47a79872d7e..4362239877ba 100644 --- a/src/Components/Forms/test/ValidationMessageStoreTest.cs +++ b/src/Components/Forms/test/ValidationMessageStoreTest.cs @@ -89,4 +89,70 @@ public void CanClearMessagesForAllFields() Assert.Empty(messages[field1]); Assert.Empty(messages[field2]); } +#nullable enable + [Fact] + public void CanAddMessagesUsingExpressionWithNullableProperty() + { + // This test verifies that the generic Add(Expression> accessor, string message) + // method works correctly with nullable types without triggering nullable reference warnings. + // + // OVERLOAD BEHAVIOR: + // 1. Generic: public void Add(Expression> accessor, string message) + // - TField is inferred as string? when expression is () => model.Text + // - No nullable warning because types match correctly + // + // 2. Non-generic: public void Add(Expression> accessor, string message) + // - Expression> requires boxing string? to object + // - Warns: "Possible null reference return" because the expression return type + // is string? but the parameter expects Func + // + // Arrange + var model = new TestModel(); + var editContext = new EditContext(model); + var messages = new ValidationMessageStore(editContext); + + // Act - Uses the generic Add overload which correctly infers TField as string? + messages.Add(() => model.Text, "This value is not valid"); + + // Assert + var fieldIdentifier = FieldIdentifier.Create(() => model.Text); + Assert.Equal(new[] { "This value is not valid" }, messages[fieldIdentifier]); + } + + [Fact] + public void CanAddMultipleMessagesUsingExpressionWithNullableProperty() + { + // This test verifies that the generic Add(Expression> accessor, IEnumerable messages) + // method works correctly with nullable types. + // + // NON-GENERIC OVERLOAD (triggers warning with nullable properties): + // public void Add(Expression> accessor, IEnumerable messages) + // => Add(FieldIdentifier.Create(accessor), messages); + // When used with () => model.Text (string?), the compiler must box string? to object, + // which causes a nullable reference warning. + // + // GENERIC OVERLOAD (no warning): + // public void Add(Expression> accessor, IEnumerable messages) + // => Add(FieldIdentifier.Create(accessor), messages); + // TField is correctly inferred as string?, avoiding the warning. + // + // Arrange + var model = new TestModel(); + var editContext = new EditContext(model); + var messages = new ValidationMessageStore(editContext); + var validationMessages = new[] { "First error", "Second error" }; + + // Act - Uses the generic Add overload + messages.Add(() => model.Text, validationMessages); + + // Assert + var fieldIdentifier = FieldIdentifier.Create(() => model.Text); + Assert.Equal(validationMessages, messages[fieldIdentifier]); + } + + private class TestModel + { + public string? Text { get; set; } + } +#nullable disable } From 7f0f7037afad4a2cb4f2be62b16a86c24b33862d Mon Sep 17 00:00:00 2001 From: BharatRamsf3693 <103921986+BharatRamsf3693@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:48:29 +0530 Subject: [PATCH 2/5] Refactor comments in ValidationMessageStoreTest --- src/Components/Forms/test/ValidationMessageStoreTest.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/Components/Forms/test/ValidationMessageStoreTest.cs b/src/Components/Forms/test/ValidationMessageStoreTest.cs index 4362239877ba..d012e48a8bfb 100644 --- a/src/Components/Forms/test/ValidationMessageStoreTest.cs +++ b/src/Components/Forms/test/ValidationMessageStoreTest.cs @@ -106,15 +106,13 @@ public void CanAddMessagesUsingExpressionWithNullableProperty() // - Warns: "Possible null reference return" because the expression return type // is string? but the parameter expects Func // - // Arrange var model = new TestModel(); var editContext = new EditContext(model); var messages = new ValidationMessageStore(editContext); - // Act - Uses the generic Add overload which correctly infers TField as string? + // Uses the generic Add overload which correctly infers TField as string? messages.Add(() => model.Text, "This value is not valid"); - // Assert var fieldIdentifier = FieldIdentifier.Create(() => model.Text); Assert.Equal(new[] { "This value is not valid" }, messages[fieldIdentifier]); } @@ -136,16 +134,14 @@ public void CanAddMultipleMessagesUsingExpressionWithNullableProperty() // => Add(FieldIdentifier.Create(accessor), messages); // TField is correctly inferred as string?, avoiding the warning. // - // Arrange var model = new TestModel(); var editContext = new EditContext(model); var messages = new ValidationMessageStore(editContext); var validationMessages = new[] { "First error", "Second error" }; - // Act - Uses the generic Add overload + // Uses the generic Add overload messages.Add(() => model.Text, validationMessages); - // Assert var fieldIdentifier = FieldIdentifier.Create(() => model.Text); Assert.Equal(validationMessages, messages[fieldIdentifier]); } From d7401f8fec60d6fab29c39aab209c1d0c5faa306 Mon Sep 17 00:00:00 2001 From: BharatRamsf3693 <103921986+BharatRamsf3693@users.noreply.github.com> Date: Thu, 11 Jun 2026 11:57:33 +0530 Subject: [PATCH 3/5] Refactor comments in ValidationMessageStoreTest --- src/Components/Forms/test/ValidationMessageStoreTest.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Components/Forms/test/ValidationMessageStoreTest.cs b/src/Components/Forms/test/ValidationMessageStoreTest.cs index d012e48a8bfb..80e419befcb0 100644 --- a/src/Components/Forms/test/ValidationMessageStoreTest.cs +++ b/src/Components/Forms/test/ValidationMessageStoreTest.cs @@ -105,7 +105,6 @@ public void CanAddMessagesUsingExpressionWithNullableProperty() // - Expression> requires boxing string? to object // - Warns: "Possible null reference return" because the expression return type // is string? but the parameter expects Func - // var model = new TestModel(); var editContext = new EditContext(model); var messages = new ValidationMessageStore(editContext); @@ -133,7 +132,6 @@ public void CanAddMultipleMessagesUsingExpressionWithNullableProperty() // public void Add(Expression> accessor, IEnumerable messages) // => Add(FieldIdentifier.Create(accessor), messages); // TField is correctly inferred as string?, avoiding the warning. - // var model = new TestModel(); var editContext = new EditContext(model); var messages = new ValidationMessageStore(editContext); From e047b3dd300b8caca1f60b0cb6a2017b4da0d092 Mon Sep 17 00:00:00 2001 From: BharatRamsf3693 <103921986+BharatRamsf3693@users.noreply.github.com> Date: Tue, 30 Jun 2026 18:41:35 +0530 Subject: [PATCH 4/5] Fix warning when using nullable properties in ValidationMessageStore.Add field accessor --- .../Forms/test/ValidationMessageStoreTest.cs | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/Components/Forms/test/ValidationMessageStoreTest.cs b/src/Components/Forms/test/ValidationMessageStoreTest.cs index 80e419befcb0..ff3fd1b65bf5 100644 --- a/src/Components/Forms/test/ValidationMessageStoreTest.cs +++ b/src/Components/Forms/test/ValidationMessageStoreTest.cs @@ -93,23 +93,10 @@ public void CanClearMessagesForAllFields() [Fact] public void CanAddMessagesUsingExpressionWithNullableProperty() { - // This test verifies that the generic Add(Expression> accessor, string message) - // method works correctly with nullable types without triggering nullable reference warnings. - // - // OVERLOAD BEHAVIOR: - // 1. Generic: public void Add(Expression> accessor, string message) - // - TField is inferred as string? when expression is () => model.Text - // - No nullable warning because types match correctly - // - // 2. Non-generic: public void Add(Expression> accessor, string message) - // - Expression> requires boxing string? to object - // - Warns: "Possible null reference return" because the expression return type - // is string? but the parameter expects Func var model = new TestModel(); var editContext = new EditContext(model); var messages = new ValidationMessageStore(editContext); - // Uses the generic Add overload which correctly infers TField as string? messages.Add(() => model.Text, "This value is not valid"); var fieldIdentifier = FieldIdentifier.Create(() => model.Text); @@ -119,25 +106,11 @@ public void CanAddMessagesUsingExpressionWithNullableProperty() [Fact] public void CanAddMultipleMessagesUsingExpressionWithNullableProperty() { - // This test verifies that the generic Add(Expression> accessor, IEnumerable messages) - // method works correctly with nullable types. - // - // NON-GENERIC OVERLOAD (triggers warning with nullable properties): - // public void Add(Expression> accessor, IEnumerable messages) - // => Add(FieldIdentifier.Create(accessor), messages); - // When used with () => model.Text (string?), the compiler must box string? to object, - // which causes a nullable reference warning. - // - // GENERIC OVERLOAD (no warning): - // public void Add(Expression> accessor, IEnumerable messages) - // => Add(FieldIdentifier.Create(accessor), messages); - // TField is correctly inferred as string?, avoiding the warning. var model = new TestModel(); var editContext = new EditContext(model); var messages = new ValidationMessageStore(editContext); var validationMessages = new[] { "First error", "Second error" }; - // Uses the generic Add overload messages.Add(() => model.Text, validationMessages); var fieldIdentifier = FieldIdentifier.Create(() => model.Text); From ce7e4d0b783a2ffd3fa38760f3ed7a2b4302bd39 Mon Sep 17 00:00:00 2001 From: BharatRamsf3693 <103921986+BharatRamsf3693@users.noreply.github.com> Date: Wed, 8 Jul 2026 15:14:14 +0530 Subject: [PATCH 5/5] Fix warning when using nullable properties in ValidationMessageStore.Add field accessor --- src/Components/Forms/src/PublicAPI.Unshipped.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Components/Forms/src/PublicAPI.Unshipped.txt b/src/Components/Forms/src/PublicAPI.Unshipped.txt index e72e4b05efd7..3e45c55a93df 100644 --- a/src/Components/Forms/src/PublicAPI.Unshipped.txt +++ b/src/Components/Forms/src/PublicAPI.Unshipped.txt @@ -3,8 +3,6 @@ *REMOVED*Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, System.Collections.Generic.IEnumerable! messages) -> void Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, string! message) -> void Microsoft.AspNetCore.Components.Forms.ValidationMessageStore.Add(System.Linq.Expressions.Expression!>! accessor, System.Collections.Generic.IEnumerable! messages) -> void -Microsoft.AspNetCore.Components.Forms.ValidationRequestedEventArgs.ValidationRequestedEventArgs(System.Threading.CancellationToken cancellationToken) -> void -Microsoft.AspNetCore.Components.Forms.ValidationRequestedEventArgs.CancellationToken.get -> System.Threading.CancellationToken Microsoft.AspNetCore.Components.Forms.ValidationRequestedEventArgs.AddAsyncValidator(System.Func! validator) -> void *REMOVED*static Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.AddDataAnnotationsValidation(this Microsoft.AspNetCore.Components.Forms.EditContext! editContext) -> Microsoft.AspNetCore.Components.Forms.EditContext! *REMOVED*static Microsoft.AspNetCore.Components.Forms.EditContextDataAnnotationsExtensions.EnableDataAnnotationsValidation(this Microsoft.AspNetCore.Components.Forms.EditContext! editContext) -> System.IDisposable!