PRACTICAL 11: VALIDATION ASSIGNMENT

Design a registration form with the following fields:
 - Full Name
 - Email Address
 - Mobile Number
 - Age
 - Password
 - Confirm Password
Implement client side and server side validations.

Validate the following:
 - Full Name should not be empty.
 - Email should be in a valid format.
 - Mobile Number should contain exactly 10 digits.
 - Age should be between 18 and 30.
 - Password must:
     - be at least 8 characters long,
     - include one uppercase letter,
     - include one lowercase letter,
     - include one number,
     - include one special character.
 - Confirm Password must match the Password.

STEPS:
1. Create ASP.NET Core Web App (MVC) project (Prac5).
2. In Models add the class Form.cs with the validation attributes.
3. In Controllers add FormController.cs.
4. In Views add the folder Form with Index.cshtml and Thanks.cshtml.
5. In Startup.cs change the default route to controller=Form.
6. Run the project and test the validations (server side and client side).

SERVER SIDE:

CODE: (Controllers/FormController.cs)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Prac5.Models;

namespace Prac5.Controllers
{
    public class FormController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }

        [HttpPost]
        public IActionResult Index(Form model)
        {
            if (ModelState.IsValid)
            {
                return RedirectToAction("Thanks");
            }
            return View(model);
        }

        public IActionResult Thanks()
        {
            return View();
        }
    }
}

CODE: (Models/Form.cs)
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;

namespace Prac5.Models
{
    public class Form
    {
        [Required(ErrorMessage = "Full Name is required")]
        public string FullName { get; set; }

        [Required(ErrorMessage = "Email is required")]
        [EmailAddress(ErrorMessage = "Invalid Email Address")]
        public string Email { get; set; }

        [Required(ErrorMessage = "Mobile Number is required")]
        [RegularExpression(@"^\d{10}$", ErrorMessage = "Mobile Number must contain exactly 10 digits")]
        public string MobileNumber { get; set; }

        [Required(ErrorMessage = "Age is required")]
        [Range(18, 30, ErrorMessage = "Age must be between 18 and 30")]
        public int Age { get; set; }

        [Required(ErrorMessage = "Password is required")]
        [RegularExpression(@"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&]).{8,}$",
        ErrorMessage = "Password must contain at least 8 characters, one uppercase, one lowercase, one number and one special character")]
        [DataType(DataType.Password)]
        public string Password { get; set; }

        [Required(ErrorMessage = "Confirm Password is required")]
        [Compare("Password", ErrorMessage = "Passwords do not match")]
        [DataType(DataType.Password)]
        public string ConfirmPassword { get; set; }
    }
}

CODE: (Views/Form/Index.cshtml)
@{
}
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/jquery-validation/dist/jquery.validate.min.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js"></script>
@model Prac5.Models.Form

<form asp-action="Index" method="post">
    <div>
        <label asp-for="FullName"></label>
        <input asp-for="FullName" />
        <span asp-validation-for="FullName"></span>
    </div>
    <div>
        <label asp-for="Email"></label>
        <input asp-for="Email" />
        <span asp-validation-for="Email"></span>
    </div>
    <div>
        <label asp-for="MobileNumber"></label>
        <input asp-for="MobileNumber" />
        <span asp-validation-for="MobileNumber"></span>
    </div>
    <div>
        <label asp-for="Age"></label>
        <input asp-for="Age" />
        <span asp-validation-for="Age"></span>
    </div>
    <div>
        <label asp-for="Password"></label>
        <input asp-for="Password" type="password" />
        <span asp-validation-for="Password"></span>
    </div>
    <div>
        <label asp-for="ConfirmPassword"></label>
        <input asp-for="ConfirmPassword" type="password" />
        <span asp-validation-for="ConfirmPassword"></span>
    </div>
    <button type="submit">Submit Form</button>
</form>

@section Scripts{
    <partial name="_ValidationScriptsPartial" />
}

CODE: (Views/Form/Thanks.cshtml)
@model Prac5.Models.Form
@{
    ViewData["Title"] = "Thanks";
}

<h1>Thankyou! Your form has been submitted!</h1>

CODE: (Startup.cs - Configure method: change only controller=Form)
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Form}/{action=Index}/{id?}");
});

OUTPUT:
Invalid input shows the error message below each field; a valid form redirects to the
Thanks page: "Thankyou! Your form has been submitted!"

CLIENT SIDE:
Run the output and inspect (right click > Inspect). The error messages appear immediately
in the browser, without a page reload, because of the jQuery validation scripts.
