如何在MVC表单上启用验证?

How to enable validation on MVC form?

提问人:Ryan Tobin 提问时间:8/21/2022 更新时间:8/21/2022 访问量:122

问:

我正在使用 MVC 构建一个网站,并且我有一个带有表单的视图。我希望当用户将字段留空时出现验证,但是我无法让它工作。我尝试在模型中添加数据注释标签,span,并在post操作中检查ModelState。 asp-validation-for

这是我的模型:

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; }

    }
}

这是我的观点:

@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 class="content">
    <div class="row">
        <div class="col-md-12">
            <div class="card card-info">
                <div class="card-header">
                    <h3 class="card-title">Edit Your Project</h3>
                </div>
                <div class="card-body">
                    <form method="post">
                        <div class="form-group">
                            <label for="inputName">Project Name:</label>
                            <textarea id="inputName" name="Name" class="form-control" rows="1">@Model.Name</textarea>
                            <span asp-validation-for="Name" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label for="inputDescription">Project Description:</label>
                            <textarea id="inputDescription" name="Description" class="form-control" rows="3">@Model.Description</textarea>
                            <span asp-validation-for="Description" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label for="inputStatus">Status:</label>
                            <select asp-for="Status" id="inputStatus" name="Status" class="form-control custom-select">
                                <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" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label for="inputCompany">Client Company:</label>
                            <textarea asp-for="ClientCompany" id="inputCompany" name="ClientCompany" class="form-control" rows="1">@Model.ClientCompany</textarea>
                            <span asp-validation-for="ClientCompany" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label for="inputLeader">Project Leader:</label>
                            <select asp-for="ProjectLeader" id="inputLeader" name="ProjectLeader" class="form-control custom-select">
                                <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" class="text-danger"></span>
                        </div>
                        <div class="form-group">
                            <label>Select 1 or More Contributors:</label>
                            <div class="select2-blue">
                                <select asp-for="Users" class="select2" name="Contributors" multiple="multiple" data-dropdown-css-class="select2-blue" 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" class="text-danger"></span>
                        </div>
                        <div class="row">
                            <div class="col-12">
                                <a asp-controller="Home" asp-action="Projects" class="btn btn-secondary">Cancel</a>
                                <input type="submit" asp-route-id="@Model.Id" value="Update Project" class="btn btn-success float-right">
                            </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>
}

最后,这是我的控制器方法:

[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);
    }

每当我提交表单并将字段留空时,页面就会刷新并且不会保存任何更改。相反,我希望弹出错误验证消息。我怎样才能做到这一点?谢谢!

C# asp.net ASP.NET-MVC 验证 模型视图控制器

评论

0赞 Abdul Haseeb 8/22/2022
Did'not use for as string 数据类型已接受 null 值。?string

答:

0赞 Ali Khan 8/21/2022 #1

要使 View 中的 html 验证能够使用 EditProjectViewModel 中定义的 asp.net 数据验证属性,您需要 javascript/jquery 非干扰行为。这将帮助您生成大部分验证代码,并根据模型中定义的数据属性为您进行验证。

您可以将此答案作为参考和帮助:什么是 jQuery Unobtrusive Validation?

评论

1赞 Ryan Tobin 8/21/2022
谢谢!如此简单,我所缺少的只是视图中的必需属性