Home > Software design >  How to enable validation on MVC form?
How to enable validation on MVC form?

Time:08-21

I am building a website with MVC and I have a view with a form. I want validation to appear when users leave a field blank, however I can not get this to work. I have tried adding the Data annotation tags in the model, the asp-validation-for span, and checking the ModelState in the post action.

Here is my Model:

using System;
using IssueTracker.Areas.Identity.Data;
using System.ComponentModel.DataAnnotations;
using System.Xml.Linq;

namespace IssueTracker.Models
{
    public class EditProjectViewModel
    {
        public EditProjectViewModel()
        {
            this.Users = new List<ApplicationUser>();
            this.OtherUsers = new List<ApplicationUser>();
        }

        public int Id { get; set; }

        [Required]
        public string? Name { get; set; }

        [Required]
        public string? Description { get; set; }

        [Required]
        public string? Status { get; set; }

        [Required]
        public string? ClientCompany { get; set; }

        [Required]
        public string? ProjectLeader { get; set; }

        [Required]
        public virtual List<ApplicationUser> Users { get; set; }

        [Required]
        public virtual List<ApplicationUser> OtherUsers { get; set; }

    }
}

and here is my View:

@using IssueTracker.Areas.Identity.Data
@using Microsoft.AspNetCore.Identity
@inject UserManager<ApplicationUser> userManager
@model EditProjectViewModel
@{
    ViewData["Title"] = "Edit Project: "   Model.Name;
}

@section Scripts2
{
    <link rel="stylesheet" href="../../dist/plugins/select2/css/select2.min.css">
}

<!-- Main content -->
<section >
    <div >
        <div >
            <div >
                <div >
                    <h3 >Edit Your Project</h3>
                </div>
                <div >
                    <form method="post">
                        <div >
                            <label for="inputName">Project Name:</label>
                            <textarea id="inputName" name="Name"  rows="1">@Model.Name</textarea>
                            <span asp-validation-for="Name" ></span>
                        </div>
                        <div >
                            <label for="inputDescription">Project Description:</label>
                            <textarea id="inputDescription" name="Description"  rows="3">@Model.Description</textarea>
                            <span asp-validation-for="Description" ></span>
                        </div>
                        <div >
                            <label for="inputStatus">Status:</label>
                            <select asp-for="Status" id="inputStatus" name="Status" >
                                <option selected value="@Model.Status">@Model.Status</option>
                                @if (Model.Status != "In Development")
                                {
                                    <option value="In Development">In Development</option>
                                }
                                @if (Model.Status != "On Hold")
                                {
                                    <option value="On Hold">On Hold</option>
                                }
                                @if (Model.Status != "Revising")
                                {
                                    <option value="Revising">Revising</option>
                                }
                                @if (Model.Status != "Completed")
                                {
                                    <option value="Completed">Completed</option>
                                }
                                @if (Model.Status != "Withdrawn")
                                {
                                    <option value="Withdrawn">Withdrawn</option>
                                }
                            </select>
                            <span asp-validation-for="Status" ></span>
                        </div>
                        <div >
                            <label for="inputCompany">Client Company:</label>
                            <textarea asp-for="ClientCompany" id="inputCompany" name="ClientCompany"  rows="1">@Model.ClientCompany</textarea>
                            <span asp-validation-for="ClientCompany" ></span>
                        </div>
                        <div >
                            <label for="inputLeader">Project Leader:</label>
                            <select asp-for="ProjectLeader" id="inputLeader" name="ProjectLeader" >
                                <option selected value="@Model.ProjectLeader">@(userManager.FindByIdAsync(Model.ProjectLeader).Result.FirstName   " "   userManager.FindByIdAsync(Model.ProjectLeader).Result.LastName)</option>
                                @foreach (ApplicationUser user in userManager.Users)
                                {
                                    if (user != userManager.FindByIdAsync(Model.ProjectLeader).Result)
                                    {
                                        <option value="@user.Id">@(user.FirstName   " "   user.LastName)</option>
                                    }
                                }
                            </select>
                            <span asp-validation-for="ProjectLeader" ></span>
                        </div>
                        <div >
                            <label>Select 1 or More Contributors:</label>
                            <div >
                                <select asp-for="Users"  name="Contributors" multiple="multiple" data-dropdown-css- data-placeholder="Select a Contributors" style="width: 100%;">
                                    @foreach (ApplicationUser user in Model.Users)
                                    {
                                        <option value="@user.Id" selected>@(user.FirstName   " "   user.LastName)</option>
                                    }
                                    @foreach (ApplicationUser user in Model.OtherUsers)
                                    {
                                        <option value="@user.Id">@(user.FirstName   " "   user.LastName)</option>
                                    }
                                </select>
                            </div>
                            <span asp-validation-for="Users" ></span>
                        </div>
                        <div >
                            <div >
                                <a asp-controller="Home" asp-action="Projects" >Cancel</a>
                                <input type="submit" asp-route-id="@Model.Id" value="Update Project" >
                            </div>
                        </div>
                    </form>
                </div>
                <!-- /.card-body -->
            </div>
            <!-- /.card -->
        </div>
    </div>
</section>
<!-- /.content -->
<!-- /.content-wrapper -->

@section Scripts{
    <script src="../../dist/plugins/select2/js/select2.full.min.js"></script>
    <script>$(function () {
            $('.select2').select2()

        })</script>
}

Lastly, here is my controller method:

[HttpPost]
    public async Task<IActionResult> EditProject(int Id, string Name, string Description, string Status, string ClientCompany,
                                                string ProjectLeader, List<string> Contributors)
    {
        if (ModelState.IsValid)
        {
            var project = await db.Projects.FindAsync(Id);

            if (project == null)
            {
                return View("Error");
            }
            else
            {
                project.Name = Name;
                project.Description = Description;
                project.Status = Status;
                project.ClientCompany = ClientCompany;
                project.ProjectLeader = ProjectLeader;
            }

            db.Entry(project).Collection("Users").Load();
            foreach (ApplicationUser user in project.Users)
            {
                db.Entry(user).Collection("Projects").Load();
                user.Projects.Remove(project);
                db.Users.Update(user);
            }
            project.Users.Clear();

            foreach (string Contributor in Contributors)
            {
                project.Users.Add(await userManager.FindByIdAsync(Contributor));
                userManager.FindByIdAsync(Contributor).Result.Projects.Add(project);
            }

            project.Users.Add(userManager.FindByIdAsync(ProjectLeader).Result);
            userManager.FindByIdAsync(ProjectLeader).Result.Projects.Add(project);

            db.Projects.Update(project);
            await db.SaveChangesAsync();

            return RedirectToAction("Projects");

        }

        return RedirectToAction("EditProject", Id);
    }

Whenever I submit a form and leave fields blank, the page just refreshes and doesn't save any changes. Instead, I want the error validation messages to pop up. How can I achieve this? Thank you!

CodePudding user response:

For the html validation in View to work with asp.net data validation attributes defined in EditProjectViewModel, you will need javascript/jquery unobtrusive behavior. That will help you generate much of the validation code as well as do the validation for you based on the data attributes defined in the model.

You can take this answer as reference and for help: What is jQuery Unobtrusive Validation?

  • Related