Fluent Validation not Working in Bootstrap 4 Modal

Viewed 733

I was using data annotation validation on my Razor Pages which worked fine. For more complex valitaion I am using Fluent Validation, which works fine for everything unless it is in a Modal.

    public class MyModel
{

    [RegularExpression(@"^Test|Prod", ErrorMessage = "Please Choose A Type")]
    public string Type { get; set; }

    }

public class MyValidator : MyValidator<MyModel>
{
    public MyValidator()
    {
        RuleFor(x => x.Username)
            .Empty()
            .When(support => x.Found == false)
            .WithMessage("Not Found");
        RuleFor(x => x.IsComplete)
            .Must(x => x.Equals(true))
            .WithMessage("Please confirm");
    }
}

Below is example modal code - I have simiplified it so sorry for any mistakes. The code in the main body validates fine, but nothing I put in a modal with Fluent Validation works - it is just submitted without checks. I have several modals all doing the same thing. Data annotation validation works fine.

<div id="" class="modal" tabindex="-1" role="dialog">    
    <div class="modal-dialog-700" role="document">
        <div class="modal-content modal-size">
            <div class="modal-header">
                <h6 class="modal-title">Test</h6>
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
            </div>
        <div class="modal-body">
            <div class="container">
                <div class="row justify-content-md-center">
                    <form asp-page-handler="update" method="post">
                        <div class="form-group">
                            <label asp-for="MyModel.Username" class="control-label">Test Code</label>
                            <textarea asp-for="MyModel.Username" class="form-control" rows="2"></textarea>
                            <span asp-validation-for="MyModel.Username" class="text-danger"></span>
                        </div>

                        <div class="form-group">
                            <button class="btn">
                                <span class="text">Update</span>
                            </button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>


@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}

I have also tried:

        RuleFor(support => support.Found.ToString())
            .Matches(@"^True$")
2 Answers

The real reason is that FluentValidation does not support all rules for client side validation.

Quoted from FluentValidation docs:

Note that not all rules defined in FluentValidation will work with ASP.NET’s client-side validation. For example, any rules defined using a condition (with When/Unless), custom validators, or calls to Must will not run on the client side. Nor will any rules in a RuleSet (although this can be changed - see the section below on “RuleSet for client-side messages”). The following validators are supported on the client:

NotNull/NotEmpty
Matches (regex)
InclusiveBetween (range)
CreditCard
Email
EqualTo (cross-property equality comparison)
MaxLength
MinLength
Length

So this is a behavior by design.

FluentValidation is a server-side framework, and does not provide any client-side validation directly. The following validators are supported on the client:

NotNull/NotEmpty
Matches (regex)
InclusiveBetween (range)
CreditCard
Email
EqualTo (cross-property equality comparison)
MaxLength
MinLength
Length

If you want to use validation rules on client-side, you can try FormHelper. Form Helper transforms server-side validations to client-side.

Nuget Package: https://www.nuget.org/packages/FormHelper

GitHub: https://github.com/sinanbozkus/formhelper

Related