dotnet / dotnet/aspnetcore

Support nullable properties in ValidationMessageStore.Add expression-based overloads

Open
#67,773 0 comments 0 reactions 0 assignees View on GitHub
api-proposal api-suggestion area-blazor
Dominant language
C#
Stars
38.4k
Forks
10.9k
Avg merge
2d 10h
Merged PRs (30d)
281

Description

## Background and Motivation

This proposal addresses the nullable-reference-type warning reported in: [ValidationMessageStore.Add field accessor parameter shows a warning for nullable properties #41338](https://github.com/dotnet/aspnetcore/issues/41338)

`ValidationMessageStore` provides overloads that allow validation messages to be associated with a field using an expression-based accessor. Today, these overloads accept `Expression>`, which causes nullable-reference-type warnings when the accessor targets a nullable property such as `string?`.

```csharp

messages.Add(() => model.Text, "This value is not valid");

```

When Text is declared as string?, the expression is converted to `Expression>`, requiring a conversion from a nullable reference type to object. Although the expression is only used to identify the field through FieldIdentifier.Create, the conversion can result in compiler nullability warnings and creates an unnecessary friction point for developers working in nullable-enabled projects.

This proposal changes the expression-based overloads to use a generic type parameter so that the original field type, including its nullability annotations, is preserved. This allows nullable properties to be used naturally without warnings while maintaining the existing runtime behavior.

Benefits include:

- Eliminates compiler nullability warnings when using nullable properties.

- Improves the developer experience for nullable-enabled applications.

## Proposed API

```diff

namespace Microsoft.AspNetCore.Components.Forms;

public sealed class ValidationMessageStore
{
- public void Add(Expression> accessor, string message)
+ public void Add(Expression> accessor, string message)

- public void Add(Expression> accessor, IEnumerable messages)
+ public void Add(Expression> accessor, IEnumerable messages)
}
```

## Usage Examples

Before:
image

After:
image

With the proposed API, TField is inferred as string?, eliminating nullable conversion warnings.

## Alternative Designs

- The existing `Expression>` overloads could be retained and users could suppress or ignore nullable warnings. However, this leaves an avoidable warning in a common nullable-enabled scenario and provides a less polished developer experience.

- Another option would be to add generic overloads while keeping the existing `Expression>` overloads.

```csharp

public void Add(Expression> accessor, string message);

public void Add(Expression> accessor, string message);

```
However, keeping both overloads would add unnecessary complexity. The generic version is more flexible and better preserves the actual type of the field, including its nullability.

## Risks

The runtime behavior is expected to remain unchanged. The methods continue to use FieldIdentifier.Create to identify the target field.

Overall, the change primarily affects compile-time type inference and nullable analysis, improving the developer experience without altering functionality.

Contributor guide

Open the contributing guide

Research direction

Start by locating the ValidationMessageStore expression-based Add overloads and the FieldIdentifier.Create call they use. Update the overloads to preserve the field type and add or adjust coverage for nullable properties, then verify that field identification and nullable-enabled usage work without warnings.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
frontend, web-dev
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.