Skip to content

Blazor static SSR SupplyParameterFromForm has issue to bind a Dictionary value which is declared after a nullable property. #56542

@sgarnovsky

Description

@sgarnovsky

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

I have the following properties in a Model class:

[Column("end_date")]
[Display(Name = nameof(Resources.CommonCaptions.EndingOn), ResourceType = typeof(Resources.CommonCaptions))]
public DateTime? EndDate { get; set; }

public Dictionary<int, WeekTimeIntervals>? WeekIntervals { get; set; }

a WeekTimeIntervals declaration is:

public class TimeInterval
{
    public DateTime? From { get; set; }
    public DateTime? To { get; set; }
}

public class WeekTimeIntervals
{
    public Dictionary<int, TimeInterval>? TimeIntervals { get; set; }
}

When the EndDate value is not provided on the form, the WeekIntervals[0].Value.TimeIntervals is bind as null, even the values for the one of time interval is set.

FormMappingContext includes the following errors:

Model.EndDate
{The value '' is not valid for 'EndDate'.}
Model.WeekIntervals[1].TimeIntervals[2].From
  {The value '' is not valid for 'From'.}
Model.WeekIntervals[1].TimeIntervals[2].To
  {The value '' is not valid for 'To'.}
Model.WeekIntervals[1].TimeIntervals[0].From
  {The value '' is not valid for 'From'.}
Model.WeekIntervals[1].TimeIntervals[0].To
  {The value '' is not valid for 'To'.}
Model.WeekIntervals[1].TimeIntervals[0]
  {'Model.EndDate' does must start with 'Model.WeekIntervals[1].TimeIntervals[0]'}
Model.WeekIntervals[1].TimeIntervals
  {'Model.EndDate' does must start with 'Model.WeekIntervals[1].TimeIntervals'}
Model.WeekIntervals[1]
  {'Model.EndDate' does must start with 'Model.WeekIntervals[1]'}
Model.WeekIntervals
  {'Model.EndDate' does must start with 'Model.WeekIntervals'}

A few errors above (at the list end) look wierd ('Model.EndDate' does must start with 'Model.WeekIntervals[1].TimeIntervals[0]').

I found a reference of this error message here: FormMappingContext.cs#L139

internal void AttachParentValue(string key, object value)
    {
        if (_pendingErrors == null)
        {
            return;
        }

        for (var i = 0; i < _pendingErrors.Count; i++)
        {
            var (errorKey, error) = _pendingErrors[i];
            if (!errorKey.StartsWith(key, StringComparison.Ordinal))
            {
                throw new InvalidOperationException($"'{errorKey}' does must start with '{key}'");
            }

            error.Container = value;
        }

        _pendingErrors.Clear();
    }

I don't understand why this method is called for the "Model.EndDate" key while attaching a value to the "Model.WeekIntervals" dictionary.

If I change the properties order to make WeekIntervals to go before the EndDate property, the issue is not reproduced.

Expected Behavior

Expect WeekIntervals[0].Value.TimeIntervals has been bind to a value sent from a form correct.

Steps To Reproduce

No response

Exceptions (if any)

It is a simple NullReferenceException

.NET Version

8.0.204

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-blazorIncludes: Blazor, Razor Components

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions