dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.16k stars 4.71k forks source link

Blazor EditForm validation only partially works when using a 'Validator component' (within a 'business logic validation' function) #49291

Closed RichardBr closed 3 years ago

RichardBr commented 3 years ago

Description

The issue is I'm not able to get a validation message to show against a field. Although the error message does appear in the validation summary.

blazorValidationIssue8Mar21

This issue is also further restricted to only complex model properties. The approach of using "ValidateComplexType", "ObjectGraphDataAnnotationsValidator" to resolve complex model property validation limitation does not help in this instance.

The sample code below which I have created to demonstrate the problem is virtually ALL code from the Microsoft docs website (https://docs.microsoft.com/en-us/aspnet/core/blazor/forms-validation). I have attached the complete source code solution BlazorTest1.zip. Simply rebuild the solution and run to test.

Index.razor


@page "/"
@using System.ComponentModel.DataAnnotations;
<h1>Starfleet Starship Database</h1>

New Ship Entry Form

@**@ @* does not work!*@

Captain's Name

@message

Star Trek, ©1966-2019 CBS Studios, Inc. and Paramount Pictures

@code { private bool disabled; private string message; private string messageStyles = "visibility:hidden"; private CustomValidator customValidator; private Starship starship = new Starship() { ProductionDate = DateTime.UtcNow };

protected override void OnInitialized()
{
    base.OnInitialized();

    customValidator = new CustomValidator();

    starship = new Starship()
    {
        ProductionDate = DateTime.UtcNow,
        Identifier = "1",
        Classification = "Defense",
        MaximumAccommodation = 100,
        IsValidatedDesign = true,
        CaptainsName = new PersonsName { Firstname = "John", Lastname = "Kirk" }
    };
}

private async Task HandleValidSubmit(EditContext editContext)
{
    bool isValid = editContext.Validate(); // Data Annotations validation

    if (isValid)
    {
        BusinessLogicValidation();
    }
}

private bool BusinessLogicValidation()
{
    customValidator.ClearErrors();

    var errors = new Dictionary<string, List<string>>();

    if (starship.Classification == "Defense" &&
            string.IsNullOrEmpty(starship.Description))
    {
        errors.Add(nameof(starship.Description),
            new List<string>() { "For a 'Defense' ship classification, 'Description' is required." });
    }

    if (starship.CaptainsName.Firstname != "James")
    {
        //errors.Add(nameof(starship.CaptainsName.Firstname), new List<string>() { "Firstname must be James" });  // does not work (as expected)!
        errors.Add("CaptainsName.Firstname", new List<string>() { "Firstname must be James" });
    }

    if (errors.Count() > 0)
    {
        customValidator.DisplayErrors(errors);
        return true;
    }
    return false;
}

}

> Starship.cs

using System; using System.ComponentModel.DataAnnotations;

namespace BlazorTest1.Client.Shared { public class Starship { [Required] [StringLength(16, ErrorMessage = "Identifier too long (16 character limit).")] public string Identifier { get; set; }

    public string Description { get; set; }

    [Required]
    public string Classification { get; set; }

    [Range(1, 100000, ErrorMessage = "Accommodation invalid (1-100000).")]
    public int MaximumAccommodation { get; set; }

    [Required]
    [Range(typeof(bool), "true", "true", ErrorMessage = "This form disallows unapproved ships.")]
    public bool IsValidatedDesign { get; set; }

    [Required]
    public DateTime ProductionDate { get; set; }

    // [ValidateComplexType]      // does not work!
    public PersonsName CaptainsName { get; set; }
}

}

> PersonsName.cs

namespace BlazorTest1.Client.Shared { public class PersonsName { public string Firstname { get; set; } public string Lastname { get; set; } } }



### Configuration

<!--
* Which version of .NET is the code running on?
* What OS and version, and what distro if applicable?
* What is the architecture (x64, x86, ARM, ARM64)?
* Do you know whether it is specific to that configuration?
* If you're using Blazor, which web browser(s) do you see this issue in?
  -->
- Blazor Wasam
- Net 5
- Chrome browser (latest)
dotnet-issue-labeler[bot] commented 3 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

Joe4evr commented 3 years ago

This has nothing to do with the .NET runtime/corelib and should be moved to dotnet/aspnetcore.

RichardBr commented 3 years ago

This has nothing to do with the .NET runtime/corelib and should be moved to dotnet/aspnetcore.

Yes your right. How do you move this to aspnetcore?

RichardBr commented 3 years ago

I have moved the issue to aspnetcore (#30740)