Hey there.
I have a data form nested in a dialog. The DTO I've created has three fields: a string, a DateOnly, and a nullable DateOnly. When the dialog is shown, the DTO is loaded with values from its parent. The trouble is that the form does not display the "Install Date" value unless I define it as nullable in the DTO. This value is never null, and is definitely assigned to the DTO along with the "Removal Date" and "Address" fields. The values for the other fields appear correctly.
The additional relevant code appears below:
<SfDataForm ID="EditForm" Model="@mplEdit" OnValidSubmit="OnValidSubmitHandler">
<FormValidator>
<DataAnnotationsValidator></DataAnnotationsValidator>
</FormValidator>
<FormItems>
<FormItem Field="@nameof(mplEdit.StreetAddress)"></FormItem>
<FormItem Field="@nameof(mplEdit.InstallDate)"></FormItem>
<FormItem Field="@nameof(mplEdit.RemovalDate)"></FormItem>
</FormItems>
<FormButtons>
<SfButton IsPrimary="true" typeof="submit">Save</SfButton>
<SfButton OnClick="OnCloseDialog">Close</SfButton>
</FormButtons>
</SfDataForm>
@code {
[CascadingParameter]
public mplLinks Parent { get; set; } = default!;
[Parameter]
public mpl? SelectedLink { get; set; } = default!;
[Parameter]
public string CardHeaderTitle { get; set; } = "";
public bool DialogVisible { get; set; } = false;
SfDialog mplEditDialog = default!;
mplDTO mplEdit = new();
public async Task ConfirmMarkDeleted()
{
bool proceed = await DialogService.ConfirmAsync("This function will mark this link as deleted.");
if (proceed)
{
await Parent.MarkLinkDeleted(SelectedLink);
}
}
public void EditLink()
{
DateOnly? removalDate = SelectedLink.RemovalDate != null ? DateOnly.FromDateTime((DateTime)SelectedLink.RemovalDate) : null;
mplEdit = new mplDTO
{
InstallDate = DateOnly.FromDateTime(SelectedLink.InstallDate),
RemovalDate = removalDate,
StreetAddress = SelectedLink.Parcel.AddressLine1
};
DialogVisible = true;
}
public async Task OnValidSubmitHandler()
{
await Parent.UpdateMeterParcelLink(SelectedLink, mplEdit);
//OnCloseDialog();
}
public void OnCloseDialog()
{
mplEdit = new();
DialogVisible = false;
}
public class mplDTO
{
[DTOValidation]
[Display(Name = "Install Date")]
[Required]
public DateOnly InstallDate { get; set; }
[DTOValidation]
[Display(Name = "Removal Date")]
public DateOnly? RemovalDate { get; set; }
[Editable(false)]
[Display(Name = "Street Address")]
public string StreetAddress { get; set; } = default!;
}
public class DTOValidationAttribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
mplDTO link = (mplDTO)validationContext.ObjectInstance;
DateTime? compare = value as DateTime?;
if (link.RemovalDate != null && link.RemovalDate < link.InstallDate)
{
return new ValidationResult("The removal date cannot be before the install date.", new[] { validationContext.MemberName });
}
if (link.RemovalDate != null && link.RemovalDate == link.InstallDate)
{
return new ValidationResult("The installation date is probably not the same as the removal date. That's a busy meter.", new[] { validationContext.MemberName });
}
return ValidationResult.Success;
}
}
}
Is there something I'm missing? If I redefine the InstallDate field as nullable, the value shows up, but then I have to manage the possible null value when I'm transferring the DTO values back to the "real" object, and it seems to me that that's more trouble than it should be. Any help would be appreciated.
Thanks,
Christopher
Edit: for the record, this is on the most recent version - 28.1.33. It was also happening in version 27.2.5.
Udhaya Kumar D.
DateOnly types, causing it to be skipped when the respective type was used, and the components were auto-generated.DateOnly and TimeOnly types are used.