ASP.NET Core 8.0 client-side validation not working

43 views Asked by At

For some reason, I cannot get the client-side validation to work from my Razor views. However when I created a Razor page by itself without using the Layout page, it works. I'm not sure why. Appreciate any help I can get. Thanks.

Here is the markup and code from my project's Layout page:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - DotNetCore8TestSite</title>

    <environment include="Development">
        <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/jquery-validate/jquery.validate.js"></script>
        <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    </environment>
    <environment include="Staging">
        <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
        <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    </environment>
    <environment include="Production">
        <link href="~/lib/bootstrap/dist/css/bootstrap.css" rel="stylesheet" />
        <script src="~/lib/jquery/dist/jquery.js"></script>
        <script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
        <script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
        <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    </environment>
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="navbar-brand" asp-area="" asp-page="/Index">DotNetCore8TestSite</a>
                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Index">Home</a>
                        </li>
                        <li class="nav-item">
                            <a class="nav-link text-dark" asp-area="" asp-page="/Privacy">Privacy</a>
                        </li>
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            &copy; 2024 - DotNetCore8TestSite - <a asp-area="" asp-page="/Privacy">Privacy</a>
        </div>
    </footer>

    @await RenderSectionAsync("Scripts", required: false)
    
</body>
</html>

And below is the markup in my Razor view:

@model DotNetCore8TestSite.Models.ContactForm

@{
    ViewData["Title"] = "CreateMessage";
    Layout = "~/Pages/Shared/_Layout.cshtml"; 
    // ViewContext.ClientValidationEnabled = true;

}

<h1>CreateMessage</h1>

<h4>ContactForm</h4>
<hr />
<div class="row">
    <div class="col-md-4">
        <form asp-action="CreateMessage" method="post">
            <div asp-validation-summary="ModelOnly" class="text-danger"></div>
            <div class="form-group">
                <label asp-for="Name" class="control-label"></label>
                <input asp-for="Name" class="form-control" />
                <span asp-validation-for="Name" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Email" class="control-label"></label>
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger"></span>
            </div>
            <div class="form-group">
                <label asp-for="Message" class="control-label"></label>
                <input asp-for="Message" class="form-control" />
                <span asp-validation-for="Message" class="text-danger"></span>
            </div>
            <div class="form-group">
                <input type="submit" value="Create" class="btn btn-primary" />
            </div>
        </form>
    </div>
</div>

<div>
    <a asp-action="Index">Back to List</a>
</div>

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

This is the code from the model class:

using Microsoft.AspNetCore.Mvc; 
using System.ComponentModel.DataAnnotations;

namespace DotNetCore8TestSite.Models 
{ 
    public class ContactForm 
    { 
        [BindProperty] 
        [Required(ErrorMessage = "Name cannot be blank"), MinLength(3)] 
        public string Name { get; set; }

        [BindProperty]
        [Required(ErrorMessage = "Email cannot be blank"), MinLength(3)]
        public string Email { get; set; }

        [BindProperty]
        [Required(ErrorMessage = "Message cannot be blank"), MinLength(5)]
        public string Message { get; set; }
    }
}

I was expecting the field validators to display the appropriate messages when the fields were validated on hitting the Create Message button, but that's not happening. On the contrary the form is posting back to the server and the Post method is being called.

Strangely, if I create a Razor page without a View and Layout page, using the same class the client-side validation works. So I have figured it has something to do with the Layout page.

0

There are 0 answers